首页 > 代码库 > Codeforces 458C Elections 贿赂选票抢主席! 线段树
Codeforces 458C Elections 贿赂选票抢主席! 线段树
题目链接:点击打开链接
题意:
给定n张选票,每张选票有2个参数,第一个参数表示这张选票选的人
第二个参数表示如果让这张选票改为选0号 的花费
问:使得0号的选票是最高的(不能有和0号相同)的最小花费
枚举0号的最终选票
那么已知0号最终选票,则有些人选票比0号大的,那些票都要买下来。
如果买完了还是达不到 最终选票,就从所有剩下的选票里找前k小的。
用线段树求前k小的数的和,然后_(:зゝ∠)_就可以了
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<vector> using namespace std; #define N 100005 #define inf 100000000 #define L(x) (x<<1) #define R(x) (x<<1|1) #define Sum(x) tree[x].sum #define Siz(x) tree[x].siz #define Lson(x) tree[x].l #define Rson(x) tree[x].r inline int Mid(int x, int y){return (x+y)>>1;} struct node{ int l, r, siz, sum; }tree[10004*4]; void push_up(int id){ Sum(id) = Sum(L(id)) + Sum(R(id)); Siz(id) = Siz(L(id)) + Siz(R(id)); } void build(int l, int r, int id){ Lson(id) = l, Rson(id) = r; Sum(id) = Siz(id) = 0; if(l==r) return ; int mid = Mid(l,r); build(l, mid, L(id)); build(mid+1, r, R(id)); } void updata(int pos, int val, int id){ if(Lson(id) == Rson(id)) { Siz(id) += val; Sum(id) += pos*val; return ; } int mid = Mid(Lson(id), Rson(id)); if(pos <= mid) updata(pos, val, L(id)); else updata(pos, val, R(id)); push_up(id); } int query(int k, int id){ if(k<=0)return 0; if(Siz(id) <= k) { return Sum(id); } if(Lson(id) == Rson(id)){ return min(Siz(id), k) * Lson(id); } int mid = Mid(Lson(id), Rson(id)); if(Siz(L(id)) <= k) { return Sum(L(id)) + query(k - Siz(L(id)), R(id)); } else query(k, L(id)); } vector<int> a[N], G[N]; int n, cost, now; int work(int x){ for(int i = 0; i < G[x].size(); i++) { cost += G[x][i]; updata(G[x][i], -1, 1); now ++; } int hehe = x - now; if(hehe<=0)return cost; return cost+query(hehe, 1); } void input(){ build(0, 10004, 1); for(int i = 0; i < N; i++)a[i].clear(), G[i].clear(); for(int i = 1; i <= n; i++) { int u, v; scanf("%d %d",&u,&v); a[u].push_back(v); updata(v, 1, 1); } for(int i = 1; i < N; i++)sort(a[i].begin(), a[i].end()); for(int i = 0; i < N; i++) { for(int j = 0; j < a[i].size(); j++) { G[a[i].size() - j].push_back(a[i][j]); } } } int main(){ int i, j, u, v; while(~scanf("%d",&n)) { input(); int ans = 1e9+10; cost = 0; now = 0; for(i = n; i >= 0; i--) { int tmp = work(i); if(tmp == -1)break; ans = min(ans, tmp); } cout<<ans<<endl; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。