Codeforces Contest 457 C Elections( 三分)
作者:互联网
题意:
有n个人要投票,第i个人会投给第ai个人。你是第0个人,你需要收买一些人使得最终你的票数比任何人的票数都多。第i个人需要bi块钱去收买。
思路:
这道题不能使用二分,因为票数与话费不成线性关系。这道题目要运用三分知识点
三分学习:
https://blog.csdn.net/Littlewhite520/article/details/70144763
这道题目可以想到的是钱数会在某个票数的时候的值最小,然后左右两边都会增大,满足y=-x2所以符合三分条件,然后贪心的求出最小的花费取min即可
#include<bits/stdc++.h>
#define fi first
#define se second
#define log2(a) log(n)/log(2)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
#define tim printf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC);
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, ll> LP;
const ll inf = 1e18;
const int N = 2e6 + 10;
const ll mod = 1e9 + 7;
const int base = 131;
const double pi = acos ( -1 );
const double eps = 1e-8;
ll vis[N], num[N], n, m, k, x, y, z;
ll a[N], b[N];
ll cx, cy, cnt, ans, sum, flag, t, ff,res;
vector<int> v[N];
map<ll, ll> mp;
set<int> sa, sb;
P p[N];
string s;
ll check(ll mid)
{
ll x=mid+cnt;
sum=0;
res=0;
for(int i=1;i<=100000;i++)
{
for(int j=0;j<=v[i].size()-x;j++) sum++,res+=v[i][j];
}
if(sum>mid) return 1e10;
t=0;
for(int i=1;i<=100000;i++)
for(int j=max(0,(int)(v[i].size()-x+1));j<v[i].size();j++) num[++t]=v[i][j];
sort(num+1,num+t+1);
for(int i=1;i<=mid-sum;i++) res+=num[i];
return res;
}
int main()
{
ios::sync_with_stdio ( false );
cin.tie ( 0 );
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
if(a[i]==0||b[i]==0) cnt++;
else
{
v[a[i]].push_back(b[i]);
}
}
for(int i=1;i<=100000;i++)
{
sort(v[i].begin(),v[i].end());
if(v[i].size()>=cnt) flag=1;
}
if(!flag) return cout<<0<<endl,0;
ll l=1,r=n,m1,m2;
ans=1e10;
while(l<=r)
{
m1=l+(r-l)/3;
m2=r-(r-l)/3;
//show2(m1,m2)
ll f1=check(m1),f2=check(m2);
//show3(" f",f1,f2)
if(f1<=f2)
{
r=m2-1;
ans=min(ans,f1);
}
else l=m1+1,ans=min(ans,f2);
}
cout<<ans<<endl;
}
标签:cnt,const,int,ll,Codeforces,Elections,457,票数,define 来源: https://blog.csdn.net/weixin_42640692/article/details/94359483