「Codeforces」#779 D2
「Codeforces」#779 D2
Description
原有 \([l,r]\) 内的整数,同时 \(\oplus x\) ,得到 \(r - l + 1\) 个数 \(a_i\),现给出 \(l, r,a_i\),找 \(x\)。
\(0 \leq l < r < 2^{17}\),\(0 \leq a_i < 2^{17}\)
Solution
在 \(D1\) 中,\(l = 0\),此时只需要按位考虑,统计每一位上 \(0,1\) 的个数,与 \([l,r]\) 这一位上 \(0,1\) 的个数进行比较,如果一样那么 \(x\) 在这一位是 \(0\),否则是 \(1\);
在 \(D2\) 中,每个二进制并没有从头开始填满,\(a_i\) 会出现”断档“,寻找断档:找 \(a_i \oplus 1\) 是否存在;
考虑最低位,如果 \(l \% 2 == 0\),\(r \% 2 == 1\),那么没有断档,\(x\) 这一位上是多少都可以,令 \(l' = l >> 1, r' = r >> 1\),递归实现即可;
否则,\(a_i\) 会出现一个或两个断档,(注意这里递归实现,断档不只是一个或两个数与整段的断开),于是寻找断档即可。
Code
import sys
input = sys.stdin.readline
def solve(l: int, r: int, s: set):
if l % 2 == 0 and r % 2 == 1:
t = set()
for i in s : t.add(i >> 1)
return solve(l >> 1, r >> 1, t) << 1
else :
for i in s:
if (i ^ 1) not in s:
flag = True
ans = i
if l % 2 == 0 : ans ^= r
else : ans ^= l
for j in s:
if (j ^ ans) < l or (j ^ ans) > r:
flag = False
break
if flag: return ans
t = int(input())
for _ in range (t):
l, r = map(int, input().split())
s = set(map(int, input().split()))
print(solve(l, r, s))