集合操作
参考了大佬的代码:boringhaker 提交的代码
先將序列a排序。
如果 a[pos] 后边的数减去 k * p的平均值大于等于 a[pos - 1],就不需要管pos前边的数。
用后缀和找到 pos 的位置。
pos后边的数减去 (a[i] - key)/p*p。
如果 k 依旧不为0,继续从大到小减去p。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6+10;
int a[N];
signed main(){
std::ios_base::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n, k, p;
cin>>n>>k>>p;
for(int i = 1; i <= n; i++){
cin>>a[i];
}
sort(a+1, a+1+n);
// 特判
if(p == 0){
for(int i = 1; i <= n; i++){
cout<<a[i]<<" ";
}
return 0;
}
int pos, key, sum = 0;
a[0] = -LLONG_MAX;
// 找到pos的位置
for(int i = n; i >= 1; i--){
sum += a[i];
if((sum - k*p)/(n-i+1) >= a[i-1]){
pos = i;
key = (sum - k*p)/(n-i+1);
break;
}
}
for(int i = n; i >= pos; i--){
k -= (a[i] - key)/p;
a[i] -= (a[i] - key)/p*p;
}
sort(a+1, a+1+n);
for(int i = n; i >= pos; i--){
if(k > 0){
a[i] -= p;
k--;
}
else{
break;
}
}
sort(a+1, a+1+n);
for(int i = 1; i <= n; i++){
cout<<a[i]<<" ";
}
return 0;
}

京公网安备 11010502036488号