zoukankan      html  css  js  c++  java
  • 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
    ",ans);    
        return 0;
    }
  • 相关阅读:
    克隆对象和对象的继承
    面向对象的目的和方式
    补充+复习
    正则的一些细节和拖拽时遇到的问题及解决方法
    js高级正则解析
    正则理解
    如何判断this指向?
    动画以及运动
    元素节点
    null和undefined的区别
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9464063.html
Copyright © 2011-2022 走看看