CF1567B MEXor Mixup 题解

\(\text{Description}\)

给你两个数字 \(a\)\(b\),问使得一个非负整数数组的 \(\operatorname{MEX}\)\(a\) ,数组内所有数的 \(\operatorname{XOR}\)\(b\) 的最短长度。

称不属于该数组的最小非负整数为该数组的 \(\operatorname{MEX}\) ,数组的 \(\operatorname{XOR}\) 为数组所有元素的按位异或。

限制

\(1\le a\le 3\times 10^5,0\le b\le 3\times 10^5,1\le T\le 5\times 10^5\)

\(\text{Solution}\)

首先,要使 \(\text{mex}\)\(a\),则需要数列中包含 \(0\sim a -1\),记 \(s = \displaystyle\bigoplus_{i=0}^{a-1}i\),则我们需要在序列中再添加一项 \(s\oplus b\),这样序列的异或和就是 \(b\) 了。

需要注意的细节:

  • 如果 \(s=b\),就不需要添加,答案为 \(a\)
  • 如果 \(s\oplus b = a\),需要添加两项,答案为 \(a+2\)
  • 剩下的答案为 \(a+1\)
  • 由于 \(T\) 比较大, 我们需要预处理前缀异或和。

Code


int a,b ;
int sum[300005] ;

inline void solve() {
    in(a,b) ;

    int x = sum[a - 1] ^ b;

    if (x == 0) 
        out('\n',a) ;
    else if (x == a) 
        out('\n',a + 2) ;
    else 
        out('\n',a + 1) ;
}

int main(int argc, const char **argv) {
#ifdef hpy
    freopen("std.in", "r", stdin);
    freopen("std.ans", "w", stdout);
#endif
    std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
    int t ;

    for (int i = 1; i <= 300000; ++i) 
        sum[i] = sum[i - 1] ^ i ;

    in(t) ;

    for (; t; --t) 
        solve() ; 

    std::cerr << "This program costs " << clock() << " ms" ;
    return 0 ;
}
posted @ 2021-09-20 20:19  feicheng  阅读(96)  评论(0)    收藏  举报