• codeforces#1251E2. Voting (Hard Version)(贪心)


    题目链接:

    http://codeforces.com/contest/1251/problem/E2

    题意:

    主角需要获得n个人的投票

    有两种方式让某个人投票

    1,已经投票的人数大于m

    2,花p枚硬币收买

    数据范围:

    $1leq n leq 200 000$

    分析: 

    对$m$进行排序

    保留前缀的$m$数组,$pre[x]$为$m$小于等于$x$的人数

    对x逆序处理,当枚举到$x$的时候,假设$m$小于等于$x-1$的那些人已经投票,也就是有$pre[x-1]$人已经投票

    如果$pre[x-1]>=x$那么不需要处理

    如果$pre[x-1]<x$那么$m$在$x$到$n$的人至少要收买$x-pre[x-1]$个人

    得到所有$x$需要收买的后缀,显然,从后往前处理最优

    AC代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define pii pair<int,int>
    using namespace std;
    const int maxn=2e5+7;
    int pre[maxn];
    vector<int>ve[maxn];
    multiset<int>se;
    int main() {
        int T,n;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                int a,b;
                scanf("%d %d",&a,&b);
                pre[a]++;
                ve[a].push_back(b);
            }
            for(int i=1;i<=n;i++)
                pre[i]+=pre[i-1];
            int cnt=0;
            ll ans=0;
            for(int i=n;i>=1;i--){
                for(int j=0;j<ve[i].size();j++)se.insert(ve[i][j]);
                int v=i-cnt-pre[i-1];
                while(v>0){
                    ans+=(*se.begin());
                    se.erase(se.begin());
                    v--;
                    cnt++;
                }
            }
            se.clear();
            for(int i=0;i<=n;i++)ve[i].clear(),pre[i]=0;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Model
    暑假集训-计算几何
    暑假集训-字符串
    将博客搬至CSDN
    codeforces #519 A A. Multiplication Table (暴力)
    bc #54 A problem of sorting
    vimrc备份
    codeforces # 317 div 2 B. Order Book(模拟)
    codeforces #317 div2 A. Arrays (水)
    bc #52 div 2 A ||hdoj5417 Victor and Machine (模拟)
  • 原文地址:https://www.cnblogs.com/carcar/p/11761552.html
Copyright © 2020-2023  润新知