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;
}
浙公网安备 33010602011771号