【Codeforces】CF 2014 H

Robin Hood Archery

#异或哈希 #博弈论 #贪心

题目描述

Sheriff of Nottingham has organized a tournament in archery. It’s the final round and Robin Hood is playing against Sheriff! There are n n n targets in a row numbered from 1 1 1 to n n n. When a player shoots target i i i, their score increases by a i a_i ai and the target i i i is destroyed. The game consists of turns and players alternate between whose turn it is. Robin Hood always starts the game, then Sheriff and so on. The game continues until all targets are destroyed. Both players start with score 0 0 0. At the end of the game, the player with most score wins and the other player loses. If both players have the same score, it’s a tie and no one wins or loses. In each turn, the player can shoot any target that wasn’t shot before. Both play optimally to get the most score possible. Sheriff of Nottingham has a suspicion that he might lose the game! This cannot happen, you must help Sheriff. Sheriff will pose q q q queries, each specifying l l l and r r r. This means that the game would be played only with targets l , l + 1 , … , r l, l+1, \dots, r l,l+1,,r, as others would be removed by Sheriff before the game starts. For each query l l l, r r r, determine whether the Sheriff can not lose the game when only considering the targets l , l + 1 , … , r l, l+1, \dots, r l,l+1,,r.

输入格式

The first line of input contains one integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104) — the number of test cases. The first line of each test case contains two integers n n n, q q q ( 1 ≤ n , q ≤ 2 ⋅ 1 0 5 1 \le n,q \le 2\cdot10^5 1n,q2105) — the number of targets and the queries Sheriff will pose. The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an ( 1 ≤ a i ≤ 1 0 6 1 \le a_i \le 10^6 1ai106) — the points for hitting each target. Then follow q q q lines, each with two integers l l l and r r r ( 1 ≤ l ≤ r ≤ n 1 \le l \le r \le n 1lrn) — the range of the targets that is considered for each query. It is guaranteed that the sum of both n n n and q q q across all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2105.

输出格式

For each query, output “YES”, if the Sheriff does not lose the game when only considering the targets l , l + 1 , … , r l, l+1, \dots, r l,l+1,,r, and “NO” otherwise. You can output the answer in any case (upper or lower). For example, the strings “yEs”, “yes”, “Yes”, and “YES” will be recognized as positive responses.

样例 #1

样例输入 #1

2
3 3
1 2 2
1 2
1 3
2 3
5 3
2 1 2 1 1
1 2
1 3
4 5

样例输出 #1

NO
NO
YES
NO
NO
YES

解题思路

首先发现后手永远不可能赢,因为先手总是可以拿最大的,只有当每个数出现的次数为偶数的时候,才会出现平局,我们要判断的就是会不会出现平局。

也就是我们需要求一个区间内出现的次数是否都是偶数,显然,这可以使用异或哈希来求解,预处理每个节点的哈希桶之后,我们只需要判断 h s [ r ] hs[r] hs[r]是否等于 h s [ l − 1 ] hs[l-1] hs[l1]即可。

代码

//solve函数
const int N = 1e6 + 10;

std::mt19937_64 rnd(time(0));
ull cnt[N], rd[N];

void solve() {
	int n, q;
	std::cin >> n >> q;
	
	std::vector<int>a(n + 1);
	for (int i = 1; i <= n; ++i) {
		std::cin >> a[i];
		rd[a[i]] = rnd();
	}

	std::vector<ull>hs(n + 1);
	for (int i = 1; i <= n; ++i) {
		hs[i] = hs[i - 1];
		hs[i] -= cnt[a[i]] * rd[a[i]];

		cnt[a[i]]++; cnt[a[i]] %= 2;

		hs[i] += cnt[a[i]] * rd[a[i]];
	}

	while (q--) {
		int l, r;
		std::cin >> l >> r;
		if (hs[r] == hs[l - 1]) {
			std::cout << "YES\n";
		}
		else {
			std::cout << "NO\n";
		}
	}
	//清空
	for (int i = 1; i <= n; ++i) {
		cnt[a[i]] = rd[a[i]] = 0;
	}
}

signed main() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);

	int t = 1;
	std::cin >> t;

	while (t--) {
		solve();
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值