题目
你现在有0…10^6这些数字供选择,让你组成一个大小恰好为n的整数集合,这个集合里面的数字各不不相同,且要求它们的异或和为x.
如整数集合为{2,3,4,5},则它们的异或和的表达式就为2^ 3 ^ 4^5.
Input
第一行两个数字n和x.
1<=n<=10^5
0<=x<=10^5
Output
如果没有这样的集合就只输出一行“NO”.
否则,第一行输出"YES";
第二行,输出n个不同的整数ai(0<=ai<=10^6).
Example
Input
5 5
Output
YES
1 2 4 5 7
Input
3 6
Output
YES
1 2 5
解释
题意:要求构造一个n个数的序列,要求n个数互不相同,且异或结果为x。
分析:
1、因为0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ (0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x) = x,
构造的n个数可以为0,1,2,3,…,(n - 3),(n - 2),(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)。
2、因为(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)可能与0,1,2,3,…,(n - 3),(n - 2)中某个数重复,因此可以通过将某两个数| (1 << 17)来避免重复。
这两个数,一个可以选择(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x),另一个可以选择与(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)不同的某个数。
3、如果(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)与n-2相同,则n-3一定与(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)不同,因此将n-3和(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)同时| (1 << 17)来避免重复。
如果(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)与n-2不同,则将n-2和(0 ^ 1 ^ 2 ^ 3 ^ … ^ (n - 3) ^ (n - 2) ^ x)同时| (1 << 17)来避免重复。
4、因为n最大为105,二进制为11000011010100000,共17位,所以将某两个数| (1 << 17),最高位可以相互抵消,又可以使n个数互不相同。
因为10e6是20位,所以将某两个数| (1 << 17)后是18位,不会超过10e6,符合题意。
5、特判一下n=1以及n=2&&x=0即可。
以上解释转自https://www.cnblogs.com/tyty-Somnuspoppy/p/7589112.html
代码
#include <cstdio>
int main(){
int n, x;
scanf("%d %d", &n, &x);
int temp = x;
for(int i = 1; i <=n-2; i++){
temp^=i;
}
if(n == 2){
if(x == 0)
printf("NO");
else{
printf("YES\n");
printf("%d %d",0, x);
}
}
else if(n == 1){
printf("YES\n%d",x);
}
else{
printf("YES\n");
if(temp == n-2){
for(int i = 0; i <= n-4; i++){
printf("%d ",i);
}
printf("%d %d %d",((n-3)|(1<<17)),n-2,(temp|(1<<17)));
}
else{
for(int i = 0; i <= n-3; i++){
printf("%d ",i);
}
printf("%d %d",((n-2)|(1<<17)),(temp|(1<<17)));
}
}
return 0;
}