题意:问是否存在n个不同的非负整数的异或和为x
思路:先拿出一个x来,则问题变成了n-1个不同的数异或和为0(n-1个数不为x),将数字化为二进制,不难发现,位数为3的全部的数的异或和为0(4^5^6^7=0),位数为4.5.6.7...都是如此,位数为1的除去0,也是如此,只有位数为2的异或和不为0,那么可以把n-1化成二进制 2^a1+2^a2+2^a3...,如n-1=6=2^2+2^1,表示6是由4和2组成的,即把n-1分为2部分,其中4个数异或和为0,另外2个数异或和也为0,由前面可知,位数为3的数一共4个,异或和为0,位数为2的异或和不为0,那么可以把这2个数再提出来,其他保持不变,即得到了一个n-3个数异或和为0,那么剩下3个数异或和为x,可另其余3个数分别为 x+2^17+2^19, x+2^17, x+2^19
AC代码:
#include "iostream" #include "iomanip" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #pragma comment(linker, "/STACK:102400000,102400000") #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a,x) memset(a,x,sizeof(a)) #define step(x) fixed<< setprecision(x)<< #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define ll long long #define endl (" ") #define ft first #define sd second #define lrt (rt<<1) #define rrt (rt<<1|1) using namespace std; const ll mod=1e9+7; const ll INF = 1e18+1LL; const int inf = 1e9+1e8; const double PI=acos(-1.0); const int N=1e5+100; int bit[100],ans[N]; int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int n, x; cin>>n>>x; if(n==2 && x==0) {cout<<"NO "; return 0;} int t=n-1,l=0,x1,x2,x3,f=0,k=0; while(t){ bit[l++]=t%2; t>>=1; } x1=x+(1<<19)+(1<<17); x2=x+(1<<19); x3=x+(1<<17); if(bit[1]==0){ cout<<"YES "; ans[++k]=x; for(int i=0; i<l; ++i){ if(bit[i]){ for(int j=1<<i; j<(1<<(i+1)); ++j){ if(f-- > 0) ans[++k]=j+(1<<19); else ans[++k]=(j==1?0:j); if(ans[k]==x) f=1, ans[k]+=(1<<19); } } } } else{ cout<<"YES "; ans[++k]=x1,ans[++k]=x2,ans[++k]=x3; for(int i=0; i<l; ++i){ if(bit[i]){ if(i==1) continue; for(int j=1<<i; j<(1<<(i+1)); ++j){ ans[++k]=(j==1?0:j); } } } } if(ans[k]>=(1<<19) && ans[k-1]<(1<<19)) ans[k-1]+=(1<<19); for(int i=1; i<=k; ++i) cout<<ans[i]<<" "; return 0; }