Codeforces 458C

458C - Elections

思路:

三分凹形函数极小值域

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=1e5+5;
const int INF=0x7f7f7f7f;
vector<int>g[N],vc;
int n;
int cost(int x){
    int need=x-g[0].size(),ans=0;
    vc.clear();
    for(int i=1;i<N;i++){
        for(int j=0;j<g[i].size();j++){
            if(g[i].size()-j>=x){
                need--;
                ans+=g[i][j];
            }
            else vc.pb(g[i][j]);
        }
    }
    sort(vc.begin(),vc.end());
    for(int i=0;i<need;i++)ans+=vc[i];
    return ans;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int a,b;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a>>b,g[a].pb(b);
    for(int i=0;i<N;i++)sort(g[i].begin(),g[i].end());
    int l=g[0].size(),r=n,m1=(l+l+r)/3,m2=(l+r+r)/3;
    while(l<r){
        if(cost(m1)>cost(m2)){
            if(l==m1)break;
            else l=m1;
        }
        else {
            if(r==m2)break;
            else r=m2;
        }
        m1=(l+l+r)/3;
        m2=(l+r+r)/3;
        //cout<<l<<' '<<r<<' '<<m1<<' '<<m2<<endl;
    } 
    int ans=INF;
    for(int i=l;i<=r;i++)ans=min(ans,cost(i));
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/widsom/p/8485663.html