DescriptionGellyfish 和 Flower 正在玩一个游戏。
该游戏包含两个长度为 n n n 的整数数组 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a 1 , a 2 , … , a n 和 b 1 , b 2 , … , b n b_1,b_2,\ldots,b_n b 1 , b 2 , … , b n ,以及一个长度为 n n n 的二进制字符串 c 1 c 2 … c n c_1c_2\ldots c_n c 1 c 2 … c n 。
还有一个整数 x x x ,初始值为 0 0 0 。
游戏进行 n n n 回合。对于 i = 1 , 2 , … , n i = 1,2,\ldots,n i = 1 , 2 , … , n ,每一回合如下进行:
如果 c i = 0 c_i = 0 c i = 0 ,那么 Gellyfish 是该回合的操作者。否则,如果 c i = 1 c_i = 1 c i = 1 ,那么 Flower 是该回合的操作者。
当前操作者必须执行以下两个操作之一:
将 x : = x ⊕ a i x := x \oplus a_i x : = x ⊕ a i ; 将 x : = x ⊕ b i x := x \oplus b_i x : = x ⊕ b i 。 这里,⊕ ⊕ ⊕ 表示按位异或操作 。
Gellyfish 希望使 x x x 的最终值尽可能小,而 Flower 则希望使它尽可能大。
如果双方都采取最优策略,求 n n n 回合后 x x x 的最终值。
n ≤ 1 0 5 , 0 ≤ a i , b i < 2 60 n\leq 10^5,0\leq a_i,b_i<2^{60} n ≤ 1 0 5 , 0 ≤ a i , b i < 2 6 0 。
Solution先让 b i b_i b i 和 r e s res r e s 异或上 a i a_i a i ,现在相当于是选择一些 b i b_i b i 给 r e s res r e s 异或上。
首先考虑只有一位怎么做。
容易发现最大的一个 b i = 1 b_i=1 b i = 1 的 i i i 可以控制这一位的最终取值,这一个 i i i 的最终取值取决于 1 ∼ i − 1 1\sim i-1 1 ∼ i − 1 的所有 b j = 1 b_j=1 b j = 1 的位置选择数量的奇偶性。
对于位数不止 1 1 1 的情况,先找到 i i i ,由于 b i b_i b i 的选择只跟其余 b j = 1 b_j=1 b j = 1 的选择数量奇偶性有关,所以让 b j ← b j ⊕ b i b_j\leftarrow b_j\oplus b_i b j ← b j ⊕ b i 后对答案的没有影响,同时最高位就只有 i i i 是 1 1 1 了,可以通过 c i c_i c i 和 r e s res r e s 在这一位的取值来确定现在的 b i b_i b i 需不需要选。
由于 b i b_i b i 的选法是固定的了,所以让 r e s res r e s 异或上 b i b_i b i 的选择后把 b i b_i b i 删掉即可,然后对后面的位做同样的事情。
时间复杂度:O ( n log V ) O(n\log V) O ( n log V ) 。
Code1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <bits/stdc++.h> #define int int64_t const int kMaxN = 1e5 + 5 ;int n;int a[kMaxN], b[kMaxN], c[kMaxN];void dickdreamer () { std::cin >> n; int res = 0 ; for (int i = 1 ; i <= n; ++i) std::cin >> a[i], res ^= a[i]; for (int i = 1 ; i <= n; ++i) std::cin >> b[i], b[i] ^= a[i]; std::string str; std::cin >> str; for (int i = 1 ; i <= n; ++i) c[i] = str[i - 1 ] - '0' ; for (int c = 60 ; ~c; --c) { int x = 0 ; for (int i = n; i; --i) { if (b[i] >> c & 1 ) { if (x) { b[i] ^= x; } else { if ((res >> c & 1 ) != ::c[i]) res ^= b[i]; x = b[i], b[i] = 0 ; } } } } std::cout << res << '\n' ; }int32_t main () {#ifdef ORZXKR freopen ("in.txt" , "r" , stdin); freopen ("out.txt" , "w" , stdout);#endif std::ios::sync_with_stdio (0 ), std::cin.tie (0 ), std::cout.tie (0 ); int T = 1 ; std::cin >> T; while (T--) dickdreamer (); return 0 ; }