Educational Codeforces Round 120 C

C. Set or Decrease

显然我们对于最优解
肯定是先减小一个数 然后再拿这个最小值更新其他值
但是这个最小值减少多少不是单调的
我们关注第二个操作 我们发现他最多就更新n次
而且每次肯定是贪心更新最大的
我们决定更新这个之后答案也可以O(1)计算出来
比如我们打算更新前i个位置 显然当前总和为 (i+1)*a[n]+sum[n-1]-sum[i](我们降序排序 a[n]就是我们最小值 拿他去更新前面i个)
要是这个大于k 我们就要让这i+1减去一些数 这些都是可以O1计算的

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
int up(int a,int b){return a<0?a/b:(a+b-1)/b;}
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl
#define NO cout<<"NO"<<endl
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int a[N];
void solve() {
    int n,k;cin>>n>>k;
    vector<int>s(n+1);
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+n+1,greater<>());
    for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i];
    int ans=INF;
    for(int i=0;i<n;i++){
        int res=(i+1)*a[n]+s[n-1]-s[i]-k;
        int pos=i;
        if(res>0)pos+=up(res,i+1);
        ans=min(pos,ans);
    }
    cout<<ans<<endl;
}
signed main(){
    fast
    int t;t=1;cin>>t;
    while(t--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-10-14 10:15  ycllz  阅读(11)  评论(0)    收藏  举报