Codeforces Round #503 (by SIS, Div. 2) C. Elections

气死我了人生中第一次打cf就掉分了

A题大水题浪费太多时间囧明明都是A两题亮老师还上分了。。

表示C题打的时候就想到正解啊(而且还更加优秀,因为家里老爷机暴力跑的超龟以为不行 其实是没认真算复杂度),虽然不会证三分性,但是最后还是AC了,暴力1000ms+ 三分40ms+

看着就很奇淫的题,猛然脑海里就想到二分政党的最后得到的选票,然后发现没有单调性,但好像满足三分

然后每次就贪心,for一遍把那些比1政党本来就有的选票+要多拿的选票还要多的拿到比这个值少1

假如还不够要多拿的,那就在剩下的拿最小的凑够

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;

int m;
LL d[3100][3100],s[3100][3100];
struct node
{
    LL d;int i,j;
    node(){}
    node(LL D,int I,int J){d=D,i=I,j=J;}
    friend bool operator >(node n1,node n2){return n1.d>n2.d;}
    friend bool operator <(node n1,node n2){return n1.d<n2.d;}
};
priority_queue<node,vector<node>,greater<node> >q;
LL check(int mid)
{
    while(!q.empty())q.pop();
    LL ret=0;int cc=0;
    mid+=d[1][0];if(mid==0)return (1LL<<62);
    for(int i=2;i<=m;i++)
    {
        if(d[i][0]>=mid)
        {
            int u=d[i][0]-mid+1;
            ret+=s[i][u];
            if(u+1<=d[i][0])q.push(node(d[i][u+1],i,u+1));
            cc+=u;
        }
        else if(d[i][0]>0)q.push(node(d[i][1],i,1));
    }
    if(cc+d[1][0]<mid)
    {
        int p=mid-(cc+d[1][0]);
        while(p--)
        {
            node t=q.top();q.pop();
            ret+=t.d;
            if(t.j+1<=d[t.i][0])q.push(node(d[t.i][t.j+1],t.i,t.j+1));
        }
    }
    return ret;
}
int main()
{
//    freopen("1.in","r",stdin);
//    freopen("1.out","w",stdout);
    
    int n,x;LL k;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)d[i][0]=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%I64d",&x,&k);
        d[x][++d[x][0]]=k;
    }
    for(int i=2;i<=m;i++)
    {
        sort(d[i]+1,d[i]+d[i][0]+1);
        s[i][0]=0;
        for(int j=1;j<=d[i][0];j++)
            s[i][j]=s[i][j-1]+d[i][j];
    }
    
    int l=0,r=n-d[1][0];
    while(r-l>3)
    {
        int mid=(l+r)/2;
        int mmid=(mid+r)/2;
        LL sum1=check(mid),sum2=check(mmid);
        if(sum1>sum2)l=mid+1;
        else r=mmid-1;
    }
    LL ans=check(l);
    for(int i=l+1;i<=r;i++)
    {
        LL dd=check(i);
        if(dd<ans)ans=dd;
    }
    printf("%I64d\n",ans);    
    return 0;
}

 

posted @ 2018-08-12 19:40  AKCqhzdy  阅读(213)  评论(0编辑  收藏  举报