题目描述(±1 Operation 2)
题目翻译
关于±1 Operation(+1或-1)操作,请见另外一番博客。
请回答个请求,每个请求会让你使用0步或者以上步骤使每个变成。代价为的绝对值。对于每个请求,回答最少需要多少步才能满足需求,也就是每一个数是一样的。
样例输入输出
样例编号 | 输入样例 | 输出样例 |
#1: | 5 3 | 10 |
#2: | 10 5 | 3316905982 |
样例解释
For Sample 1:We have and three questions in this input.
For the first question, you can change every element of A to 5 in 10 operations as follows.
- Subtract 1 from .
- Subtract 1 from six times.
- Add 1 to three times.
It is impossible to change every element of A to 5 in 9 or fewer operations.
For the second question, you can change every element of A to 20 in 71 operations.
For the third question, you can change every element of A to 0 in 29 operations.
For Sample #2: The output may not fit into -bit integers.
思路
这题一看,大家都会说:小菜一碟!外循环Q次,每次一个数,再弄一个变量清零,每次用|Ai-X|累加,不就行了吗?想的很好,但是仔细看题,你会惊慌失措、十分尴尬、不知所措。
!!!!!
什么?20万!算一算,20万的平方是400亿!两重循环直接爆!那,怎们办?看下面:
这个图可能有点看不懂,我来解释一下:横线处为Ai,下面的小圆圈为 每个X,那么只要算出每个X和要求的Ai的差再加起来就行了。有人说?这不还是平方吗?没事,预处理可以弄出个类似于前缀差的东西。那么只要用末项即可。时间复杂度O(1)。前缀差怎么来?先算出前缀和,然后用要求的Ai一减就行了。看下面:
看得出来,是要不断地接近X,那K就是不断接近的过程。k怎么来?二分查找!所以看得出来,这道题与本场比赛的C题很类似。只不过是多了一个前缀和。复杂度。
下面是代码:
代码/程序参考/禁止复制粘贴
官方程序:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,q;
cin >> n >> q;
vector<long long> a(n);
for(auto &nx : a){cin >> nx;}
sort(a.begin(),a.end());
vector<long long> rw(n+1,0);
for(long long i=0;i<n;i++){rw[i+1]=rw[i]+a[i];}
for(int i=0;i<q;i++){
long long x;
cin >> x;
int st=0,fi=n-1;
while(st<=fi){
int te=(st+fi)/2;
if(a[te]<x){st=te+1;}
else{fi=te-1;}
}
long long res=x*st;
res-=rw[fi+1];
res+=(rw[n]-rw[st]);
res-=x*(n-st);
cout << res << '\n';
}
return 0;
}