0
点赞
收藏
分享

微信扫一扫

工厂模式(简单工厂模式+工厂模式)

seuleyang 2024-05-28 阅读 10
算法c++

大致题意:

题意:给定一个长度为n (n < 1 e 5 1e^5 1e5) 的数组,进行q(< 1 e 5 1e^5 1e5)次对原数组的查询,问最小进行几次操作使得第k大的数为x (< 1 e 9 1e^9 1e9),每次操作可以选择数组的某个数加1。
思路:二分+前缀和
首先对数组从大到小进行排序,然后求前缀和。
对于每次查询,二分查找找到第一个大于等于x的位置idx,答案为 s [ i d x ] + 1 ∗ ( k − i d x ) ∗ x − s [ k ] s[idx]+1*(k-idx)*x-s[k] s[idx]+1(kidx)xs[k],注意题目可能存在爆int,需要开long long。

C++代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
LL s[N];
int main()
{
	int n,q,x,k;
	cin>>n>>q;
	vector<int> v;
	for(int i=0;i<n;i++)
	{
		cin>>x;
		v.push_back(x);
	}
	
	//逆序排列
	sort(v.rbegin(),v.rend());
	//求前缀和
	for(int i=1;i<=n;i++)
		s[i]=s[i-1]+v[i-1];
	while(q--)
	{
		cin>>k>>x;
		if(v[k-1]>x) //最小数比x还要大
		{
			puts("Impossible");
		}
		else{
            int idx=0;
			int l=0,r=n-1;
			while(l<r)
			{
				int mid=(l+r)>>1;
				if(v[mid]<x) r=mid;
				else l=mid+1;
			}
			idx=l;
			cout<<s[idx]+1ll*(k-idx)*x-s[k]<<endl;
		}
	}
	
	
	return 0;
} 
举报

相关推荐

0 条评论