集合操作
https://ac.nowcoder.com/acm/contest/11173/C
#include <bits/stdc++.h>
using namespace std;
#define int long long
using LL = long long;
template <typename T>void read(T &x){
x=0;T f=1;
char ch=getchar();
while(!isdigit(ch)){ if(ch=='-')f=-1;ch=getchar(); }
while(isdigit(ch)){ x=(x<<3)+(x<<1)+ch-'0';ch=getchar(); }
x*=f;
}
template <typename T>void print(T x){
if(x<0){ putchar('-');x=-x; }
if(x>9)print(x/10);putchar(x%10+'0');
}
template <typename T>T Abs(T x){ return x>0?x:-x; }
const int Maxn = 1e6;
const LL Maxr = 1e18;
int n;
LL k, p;
LL a[Maxn + 5],tema[Maxn + 5];
bool check (LL x) {
LL temp = a[n] - x * p;
LL sum = 0;
for (int i = 1; i <= n; i++){
if (a[i] <= temp) continue;
sum += (a[i] - temp) / p;
}
return sum >= k;
}
struct Node {
int idx;
LL val;
Node () {}
Node (int IDX,LL VAL) {
idx=IDX;
val=VAL;
}
bool operator < (const Node &x) const {
return val > x.val;
}
};
priority_queue <Node> q;
void solve(LL x) {
LL temp=a[n] - x * p;
LL sum = 0;
for (int i = 1; i <= n; i++) {
if (a[i] < temp) continue;
sum += (a[i] - temp) / p;
a[i] -= (a[i] - temp) / p * p;
q.push (Node (i, a[i]));
}
for (int i=1; i <= sum - k; i++) {
Node tem = q.top(); q.pop ();
while(a[tem.idx] + p > tema[tem.idx]) {
tem = q.top(); q.pop();
}
a[tem.idx] += p;
tem.val += p;
q.push (tem);
}
sort (a + 1, a + 1 + n);
for(int i = 1; i <= n; i++) {
print(a[i]); putchar(' ');
}
}
signed main()
{
read (n); read (k); read (p);
for (int i = 1; i <= n; i++) {
read (a[i]);
}
sort (a + 1, a + 1 + n);
memcpy(tema, a, sizeof a);
if (p == 0) {
for (int i = 1; i <= n; i++)
printf("%lld ", a[i]);
return 0;
}
LL l =0 , r = Maxr * 2 / p;
while (l + 1 < r){
LL mid = l + r >> 1;
if (check (mid)) r = mid;
else l = mid;
}
if(check (l)) solve (l);
else solve (r);
return 0;
}

浙公网安备 33010602011771号