CF457C C. Elections
题目链接
大意:有n个人,每个人有两个参数 a,b,表示第 i−th人投a,让他改变注意需要b的代价。问你现在要使得投0的人最多,最少代价是多少?
思路:我们枚举其他人被投的最大次数,然后把多的全部投0,剩下的不够的再加上。
用一个线段树维护一下前x小的和就行了。
注意要特判一下一开始就合法的情况。
细节见代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define LL long long
#define SZ(X) X.size()
#define pii pair<int,int>
#define ALL(X) X.begin(),X.end()
using namespace std;
LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
LL lcm(LL a, LL b) {return a / gcd(a, b) * b;}
LL powmod(LL a, LL b, LL MOD) {LL ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
const int N = 2e5 + 11;
int n;
int a[N],b[N],c[N];
vector<int>v[N];
set<int>Q[N];
int T[N],t[N*40];
LL s[N*40];
#define mid (l+r>>1)
#define ls o<<1
#define rs o<<1|1
void update(int o,int l,int r,int d,int val){
t[o]+=val;
s[o]+=d*val;
if(l==r)return ;
if(d<=mid)update(ls,l,mid,d,val);
else update(rs,mid+1,r,d,val);
}
LL get(int o,int l,int r,int k){
//cout<<o<<' '<<l<<' '<<r<<' '<<k<<endl;
if(t[o]<=k)return s[o];
if(l==r)return 1ll*min(k,t[o])*l;
if(t[ls]>=k)return get(ls,l,mid,k);
else return get(rs,mid+1,r,k-t[ls])+s[ls];
}
int main() {
ios::sync_with_stdio(false);
cin>>n;
int sta=0;
for(int i=1;i<=n;i++){cin>>a[i]>>b[i],c[i]=a[i];if(a[i])update(1,0,200000,b[i],1);if(!a[i])sta=1;}
if(!sta){a[++n]=0;b[n]=0;c[n]=0;}
sort(c+1,c+1+n);
int x=unique(c+1,c+1+n)-c-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(c+1,c+1+x,a[i])-c,v[a[i]].pb(b[i]);
for(int i=2;i<=x;i++){
sort(ALL(v[i]));
reverse(ALL(v[i]));
Q[SZ(v[i])].insert(i);
}
int cnt=SZ(v[1])-(!sta);
LL ans=0;
LL res=LLONG_MAX;
if(cnt>(n-(!sta))/2+1)return cout<<0<<endl,0;
for(int i=n;i>=0&&i>=cnt;i--){//枚举其他的最大人数是i 如果已经超过i了就break
vector<int>re;
for(auto k=Q[i+1].begin();k!=Q[i+1].end();k++){//把超过的部分删掉
if(*k==1)continue;
ans+=v[*k].back();
update(1,0,200000,v[*k].back(),-1);
v[*k].pop_back();
cnt++;
re.pb(*k);
}
for(auto k:re){
Q[i+1].erase(k);
Q[i].insert(k);
}
res=min(res,ans+get(1,0,200000,max(0,min(i+1,(n-(!sta))/2+1)-cnt)));
}
cout<<res<<endl;
return 0;
}