拼多多笔试题目

大致题意:

题意:给定一个长度为n (n < 1e51e^51e5) 的数组,进行q(<1e51e^51e5)次对原数组的查询,问最小进行几次操作使得第k大的数为x (<1e91e^91e9),每次操作可以选择数组的某个数加1。
思路:二分+前缀和
首先对数组从大到小进行排序,然后求前缀和。
对于每次查询,二分查找找到第一个大于等于x的位置idx,答案为s[idx]+1∗(k−idx)∗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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay_fearless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值