CF457C Elections 题解 二分

Elections

传送门

You are running for a governor in a small city in Russia. You ran some polls and did some research, and for every person in the city you know whom he will vote for, and how much it will cost to bribe that person to vote for you instead of whomever he wants to vote for right now. You are curious, what is the smallest amount of money you need to spend on bribing to win the elections. To win elections you need to have strictly more votes than any other candidate.

Input

First line contains one integer n n n ( 1 < = n < = 1 0 5 1<=n<=10^{5} 1<=n<=105 ) — number of voters in the city. Each of the next n n n lines describes one voter and contains two integers a i a_{i} ai and b i b_{i} bi ( 0 < = a i < = 1 0 5 ; 0 < = b i < = 1 0 4 0<=a_{i}<=10^{5}; 0<=b_{i}<=10^{4} 0<=ai<=105;0<=bi<=104 ) — number of the candidate that voter is going to vote for and amount of money you need to pay him to change his mind. You are the candidate 0 0 0 (so if a voter wants to vote for you, a i a_{i} ai is equal to zero, in which case b i b_{i} bi will also be equal to zero).

Output

Print one integer — smallest amount of money you need to spend to win the elections.

Examples

input #1

5
1 2
1 2
1 2
2 1
0 0

output #1

3

input #2

4
1 2
1 2
2 1
0 0

output #2

2

input #3

1
100000 0

output #3

0

以上来自 C o d e F o r c e s 以上来自CodeForces 以上来自CodeForces

题目翻译

你正在竞选俄罗斯一个小城市的州长。你做了一些民意调查和研究,知道这个城市里的每个人都会把票投给谁,也知道贿赂这个人把票投给你而不是他现在想投给的人需要多少钱。你很好奇,要想赢得选举,你需要花最少的钱来贿选。要在选举中获胜,你需要拥有严格意义上比其他候选人更多的选票。

输入格式

第一行包含一个整数 n ( 1   ≤   n   ≤   1 0 5 ) n(1 \le n \le 10^5) n(1 n 105)–城市中的选民人数。接下来的每 n n n 行描述一个选民,并包含两个整数 a i , b i ( 0   ≤   a i   ≤   1 0 5 ; 0   ≤   b i   ≤   1 0 4 ) a_i,b_i(0 \le a_i \le 10^5;0 \le b_i \le 10^4) ai,bi(0 ai 105;0 bi 104)–选民将要投票给的候选人的编号,以及你需要付给他多少钱才能让他改变主意。你是候选者 0 0 0(因此,如果投票者想投你的票, a i a_i ai 等于零,那么 b i b_i bi 也等于零)。

输出格式

输出一个整数——赢得选举所需花费的最小金额。

翻译: D e e p L + 本人 翻译:DeepL+本人 翻译:DeepL+本人

解题思路

可以发现买多少票和花费成正比,所以可以二分需要多少张票,然后问题就会转化成已知要多少张票,然后用贪心求花费的最小值。
考虑怎么买票超过自己的对手:假设需要 x x x 张票,那么所有票数大于等于 x x x 的人的票都得买走,否则他们就会阻止我当州长;其次,我肯定要买相对便宜的,所以要对票价排序;最后,如果我买了这些票数大于等于 x x x 的人的票后还不够 x x x 张,那我就不得不从剩下的票池里买了,而且也一定会去买便宜的。以上操作用vector维护即可。
看上去很难,实际一点都不简单。

AC Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int Maxn = 100000;
int n;
vector<int> arry[Maxn + 5];
int ans;
//{
inline void Input();
//
inline void Solve();
inline void init();
inline int Binary_search();
inline bool Check(int mid);
inline int Get_Answer(int x);
//
inline void Output();
//}
inline void work() {
	Input();
	Solve();
	Output();
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	work();
	return 0;
}
//{
inline void Input() {
	cin >> n;
	int a_i, b_i;
	for (int i = 1; i <= n; i++) {
		cin >> a_i >> b_i;
		arry[a_i].push_back(b_i);
	}
}
//
inline void Solve() {
	init();
	ans = Binary_search();
}
inline void init() {
	for (int i = 1; i <= Maxn; i++) {
		sort(arry[i].begin(), arry[i].end());
	}
}
inline int Binary_search() {
	int l = 1, r = n, mid;
	while (l <= r) {
		mid = l + r >> 1;
		if (Check(mid)) {
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	return Get_Answer(l);
}
inline bool Check(int mid) {
	return Get_Answer(mid) < Get_Answer(mid + 1);
}
inline int Get_Answer(int x) {
	int tot = 0, len1 = arry[0].size();
	vector<int> veco;
	for (int i = 1; i <= Maxn; i++) {
		int j = 0, len2 = arry[i].size();
		while (len2 >= x) {
			tot += arry[i][j++];
			len2 -= 1, len1 += 1;
		}
		while (j < arry[i].size()) {
			veco.push_back(arry[i][j++]);
		}
	}
	sort(veco.begin(), veco.end());
	for (int i = 0; i < veco.size(); i++) {
		if (len1 >= x) {
			break;
		}
		tot += veco[i], len1 += 1;
	}
	return tot;
}
//
inline void Output() {
	cout << ans << endl;
}
//}
  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值