7.20 希望渺茫
P11209 『STA - R8』小熊游景点 II
观察题目容易想到 01-trie,发现 \(a_i\) 和 \(b_i\) 必然存在一起。
考虑插入每一位的情况,即 \((0, 0), (0, 1), (1, 0), (1, 1)\)。
这样每个节点有可能有 \(4\) 个儿子,统计答案容易,但统计答案的过程可能是一棵二叉树,时间复杂度 \(\mathcal{O}(qn\log n)\)。
我就这么做的
而对于 \(k\) 的某位,可以直接出答案的有 \((0, 1), (1, 1)\),分讨。而接下来访问的是 \((0, 0), (1, 1)\) 或 \((1, 0), (0, 1)\),将两种情况合并成一点。查询形如一条链,时间复杂度 \(\mathcal{O}(q\log n)\)。
别读了,退役吧
我不认为我不会这么简单的题,我同样不认为下次在考场上能应对类似的情况
一定要好好算时间复杂度。
code
const int N = 5e5 + 5;
int T, n, m, a[N], b[N], l;
int sz[N * 30][4], tot = 1, trie[N * 30][2];
void ins(int pos) {
int p = 1;
per(i, 29, 0) {
int bita = a[pos] >> i & 1, bitb = b[pos] >> i & 1; sz[p][bita * 2 + bitb]++;
if (!trie[p][bita ^ bitb]) trie[p][bita ^ bitb] = ++tot;
p = trie[p][bita ^ bitb];
}
}
int query(int k) {
int p = 1, ans = 0;
per(i, 29, 0) {
int bit = k >> i & 1;
if (i == 0) ans += sz[p][2 * bit] + sz[p][3 - 2 * bit];
ans += sz[p][bit * 2 + 1];
if (trie[p][bit]) p = trie[p][bit];
else break;
}
return ans;
}
int main() {
read(T, n, m);
rep(i, 1, n) read(a[i]);
rep(i, 1, n) read(b[i]);
rep(i, 1, n) ins(i);
while (m--) {
int k; read(k); k = k ^ (l * T);
write(l = query(k), '\n');
}
return 0;
}
浙公网安备 33010602011771号