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);
}