原题链接
题目
给一个长度为 nnn 的序列 aaa
构造一个字典序最小的数组 bbb
使 aia_iai? xorxorxor bib_ibi? (1<=i<=n)(1<=i<=n)(1<=i<=n) 后满足 aia_iai? andandand ai+1a_{i + 1}ai+1? ====== aia_iai? (1<=i<=n?1)(1<=i<=n - 1)(1<=i<=n?1)
思路
一个数 xor0xor \ 0xor 0 等于它本身
一个数 andandand 本身等于 000
那么为了字典序最小,b1b_1b1? 肯定是 000,后面答案唯一。为了使 aia_iai? andandand ai?1=aia_{i - 1}\ =\ a_iai?1? = ai?,将 aia_iai? 和 ai?1a_{i-1}ai?1? 换成二进制,使 ai?1a_{i-1}ai?1? 有 111 的位置,aia_iai? 也要是 111,那么就用 ai?1oraia_{i-1}\ or\ a_iai?1? or ai?,找出所有有 111 的位置,然后再减去 aia_iai? 上原本有的 111,这样这个数与 aia_iai? xorxorxor 后所有 111 的位置肯定都包含了 ai?1a_{i-1}ai?1? 上有 111 的位置。
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;cin >> t;while (t -- ){
int n;cin >> n;int a[n + 10] ;for (int i = 1; i <= n; i ++ ){
cin >> a[i];}cout << 0 << " ";for (int i = 2; i <= n; i ++ ){
int x = (a[i] | a[i - 1]) - a[i];a[i] ^= x;cout << x << " ";}
// cout << endl;
// for (int i = 1; i <= n; i ++ ) cout << a[i] << " ";cout << endl;}return 0;
}
总结
位运算,要好好琢磨琢磨。