汤姆波利伯~题目在这里。
唔,写了快一下午,自己没想出来,还是靠别人的,二分三分,唉。。。
三分(√ )
线段树 ( )
1 #include<bits/stdc++.h> 2 #include<algorithm> 3 #include<iostream> 4 #define mem(a) memset(a,0,sizeof(a)) 5 #define ll long long 6 #define inf 0x3f3f3f3f 7 const int N=1e5+5; 8 const int mod=1e9+7; 9 using namespace std; 10 int p,q,y[N],tx,ty; 11 char s[N]; 12 int n,mx,a,b; 13 vector<int>ve[N],v; 14 ll third(int tag) 15 { 16 int ans=0; 17 int need=tag-ve[0].size(); //预设想要拿的票数减去现有票数,即还需几票 18 v.clear(); 19 for(int i=1;i<=mx;i++) //遍历每个人 20 { 21 for(int j=0;j<ve[i].size();j++) 22 { 23 if(ve[i].size()-j>=tag) //要把多数派做掉先,tag可能设的太小,所以其实可能会超 24 { 25 ans+=ve[i][j];//已经排过序了,所以从小到大放心拿 26 need--; 27 } 28 else 29 v.push_back(ve[i][j]); 30 } 31 } 32 sort(v.begin(),v.end()); 33 for(int i=0;i<need;i++) //如果还不够,排完序继续拿 34 ans+=v[i]; 35 return ans; 36 } 37 int main() 38 { 39 cin>>n; 40 for(int i=0;i<n;i++) 41 { 42 cin>>a>>b; 43 ve[a].push_back(b); 44 mx=max(mx,a); 45 } 46 for(int i=1;i<=mx;i++) 47 sort(ve[i].begin(),ve[i].end()); 48 int l=0,r=n; //不是每个人,而是票数 (。>︿<)_θ 49 while(l+2<r) //这里注意要留常数特判,因为可能lr因为下面等于的原因,会漏掉之类 50 { 51 // cout<<"***"<<l<<" "<<r<<endl; 52 int mid=(l+r)>>1,mmid=(mid+r)>>1; 53 if(third(mid)>third(mmid)) l=mid; 54 else r=mmid; 55 // cout<<"---"<<l<<" "<<r<<endl; 56 } 57 ll ans=inf; 58 for(int i=l;i<=r;i++) 59 ans=min(third(i),ans); 60 cout<<ans<<endl; 61 return 0; 62 }贿赂~