欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

【Codeforces】CF 2014 H

最编程 2024-10-07 19:57:18
...

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();
	}
};