chenfy27的刷题记录

导航

abc250E 判断前缀构成的集合是否相等

给定数组A[n]和B[n],有Q组询问,每次给出一组(x,y),问A中前x个元素构成的集合是否与B中前y个元素构成的集合相等?
1<=n,q<=2e5; 1<=a[i],b[i]<=1e9; 1<=x[i],y[i]<=n

可以用乘法和异或来实现对集合的哈希,另外需要借助一个set来避免重复元素对哈希结果的影响。

#include <bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;

struct hval {
	u64 h1, h2, h3;
	u64 f1(u64 x) { return 19260817 + 1237123ULL * x * x * x; }
	u64 f2(u64 x) { return 71806291 + 3217321ULL * x * x; }
	u64 f3(u64 x) { return 74328249 + 1678931ULL * x; }
	void set(int x) {
		h1 = f1(x & 0x7fffffff) + f1(x >> 31);
		h2 = f2(x & 0x07ffffff) + f2(x >> 27);
		h3 = f3(x & 0x00007fff) + f3(x >> 15);
	}
	hval(u64 a=0, u64 b=0, u64 c=0):h1(a), h2(b), h3(c) {}
	bool operator==(const hval &rhs) const {
		return h1 == rhs.h1 && h2 == rhs.h2 && h3 == rhs.h3;
	}
	friend hval operator+(const hval &a, const hval &b) {
		return hval(a.h1 + b.h1, a.h2 + b.h2, a.h3 + b.h3);
	}
	friend hval operator-(const hval &a, const hval &b) {
		return hval(a.h1 - b.h1, a.h2 - b.h2, a.h3 - b.h3);
	}
};

void solve() {
	int N;
	std::cin >> N;
	std::vector<int> a(N+1), b(N+1);
	for (int i = 1; i <= N; i++) {
		std::cin >> a[i];
	}
	for (int i = 1; i <= N; i++) {
		std::cin >> b[i];
	}

	std::set<int> sta;
	std::vector<hval> ha(N+1);
	for (int i = 1; i <= N; i++) {
		if (sta.count(a[i]) == 0) {
			sta.insert(a[i]);
			ha[i].set(a[i]);
		}
		ha[i] = ha[i] + ha[i-1];
	}

	std::set<int> stb;
	std::vector<hval> hb(N+1);
	for (int i = 1; i <= N; i++) {
		if (stb.count(b[i]) == 0) {
			stb.insert(b[i]);
			hb[i].set(b[i]);
		}
		hb[i] = hb[i] + hb[i-1];
	}

	int Q;
	std::cin >> Q;
	for (int i = 1; i <= Q; i++) {
		int x, y;
		std::cin >> x >> y;
		if (ha[x] == hb[y]) {
			std::cout << "Yes\n";
		} else {
			std::cout << "No\n";
		}
	}
}

int main() {
	std::cin.tie(0)->sync_with_stdio(0);
	int t = 1;
	while (t--) solve();
	return 0;
}

posted on 2024-03-18 22:53  chenfy27  阅读(18)  评论(0)    收藏  举报