题解:P10785 [NOI2024] 集合
Usada_Pekora · · 题解
当值 Yes。
想办法维护下标集合的出现次数,对下标集合 hash 一下就好做了,给每个位置赋一个 xor,冲突的概率是
到这里可以莫队,用 unordered_map 维护,Yes。
但 Yes 存在分界点
#include <bits/stdc++.h>
#define pb emplace_back
#define mkp make_pair
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
template<typename T> inline bool chkmin(T &x, const T &y) {
return (y < x) && (x = y, true);
}
template<typename T> inline bool chkmax(T &x, const T &y) {
return (x < y) && (x = y, true);
}
constexpr int N = 1e6 + 5;
int n, m, q, a[N][3], b[N][3], p[N], tot;
ull A[N], B[N], rd[N];
mt19937 rng(1u * time(NULL));
inline void ins(ull x, int opt) {
static unordered_map<ull, int> cnt;
if (cnt[x] != 0)
tot--;
if ((cnt[x] += opt) != 0)
tot++;
}
inline void work(int i) {
for (int j = 0; j < 3; j++) {
ins(A[a[i][j]], -1), A[a[i][j]] ^= rd[i], ins(A[a[i][j]], 1);
ins(B[b[i][j]], 1), B[b[i][j]] ^= rd[i], ins(B[b[i][j]], -1);
}
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
for (int j = 0; j < 3; j++)
cin >> a[i][j];
for (int i = 1; i <= n; i++)
for (int j = 0; j < 3; j++)
cin >> b[i][j];
for (int i = 1; i <= n; i++)
rd[i] = rng();
for (int l = 1, r = 0; l <= n; l++) {
while (r <= n && tot == 0)
work(++r);
p[l] = r;
work(l);
}
while (q--) {
int l, r;
cin >> l >> r;
cout << ((p[l] > r) ? "Yes\n" : "No\n");
}
return 0;
}