260720贪心I ARC220C
反悔贪心。
我们要贪心地使前面的数变成
- 若
f\ge d ,则可以使d 个区间在i-1 结束,只保留f-d 个区间。此时i 位置的值为(a_i+f-d)\bmod m=0 。 - 还可以在
i 处新开m-d 个区间。此时i 位置的值为(a_i+f+m-d)\bmod m=0 。
由于关掉区间不需要花费,所以我们优先关区间。但是,如此我们无法再将这
当
- 如果剩余
k<tp ,则我们无论如何都不能使a_i=0 。此时将小根堆和f 清空即可。 - 否则,我们将该处的决策由一改为二。这样我们就可以用
tp 的代价使f 增加m ,此时的f 就足够减去d 了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3e5+2;
int a[N];
priority_queue<int,vector<int>,greater<int>> pq;
signed main(){
int t;cin>>t;
while(t--){
while(!pq.empty()) pq.pop();
int n,m,k;cin>>n>>m>>k;
for(int i=1; i<=n; i++) cin>>a[i];
int f=0;
for(int i=1; i<=n; i++){
int d=(a[i]+f)%m;
pq.push(m-d);
if(f<d){
int tp=pq.top();pq.pop();
if(k<tp){
f=0;
while(!pq.empty()) pq.pop();
}
else k-=tp,f+=m-d,a[i]=0;
}
else f-=d,a[i]=0;
}
for(int i=1; i<=n; i++) cout<<a[i]<<" \n"[i==n];
}
return 0;
}