C. Permutation Counting

原题链接

题解

给定一个数组,你知道怎么计算最终答案吗?
设数组大小为 \(n\),数组中的最小值为 \(x\),大于最小值的个数为 \(p\)
\(ans=n*x-(n-1)+p\)\(p\in[0,n-1]\)

所以 \(x\) 越大,\(ans\) 越大
二分的前置条件有了
二分 \(x\) 遍历数组判断 \(k\) 能否达到这个 \(x\)

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[200005]={0};
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    ll t;
    cin>>t;
    while(t--)
    {
        ll n,k;
        cin>>n>>k;
        for(ll i=1;i<=n;i++) cin>>a[i];

        ll l=1,r=2e12+1;
        while(l+1<r)
        {
            ll mid=(l+r)/2;
            ll tem=k;
            for(ll i=1;i<=n;i++) if(a[i]<mid) tem-=mid-a[i];
            if(tem>=0) l=mid;
            else r=mid;
        }
        ll cnt0=0,cnt1=0,tem=k;
        for(ll i=1;i<=n;i++)
        {
            if(a[i]<=l)//这里是小于等于,因为刚补齐
            {
                tem-=l-a[i];
                cnt0++;
            }
            else cnt1++;
        }
        //cout<<l<<":\n";
        cout<<l*n-(n-1)+cnt1+min(cnt0,tem)<<"\n";
    }
    return 0;
}

posted @ 2024-05-14 19:16  纯粹的  阅读(22)  评论(0)    收藏  举报