位运算。
两个数的和:$A+B=(AandB)+(AorB)$,那么$b[i]+c[i]=n*a[i]+suma$。可以解出一组解,然后再按位统计贡献验证一下。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<ctime> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0); void File() { freopen("D:\in.txt","r",stdin); freopen("D:\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0; while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } } LL sum,sumc,sumb; LL t[70],g[70],a[200010],b[200010],c[200010]; int n; int main() { g[0]=1; for(int i=1;i<=62;i++) g[i]=g[i-1]*2; cin>>n; for(int i=1;i<=n;i++) { cin>>b[i]; sumb=sumb+b[i]; } for(int i=1;i<=n;i++) { cin>>c[i]; sumc=sumc+c[i]; } if((sumb+sumc)%(LL)(2*n)!=0) { printf("-1 "); return 0; } sum=(sumb+sumc)/(LL)(2*n); for(int i=1;i<=n;i++) { if((b[i]+c[i]-sum)<0) { printf("-1 "); return 0; } if((b[i]+c[i]-sum)%(LL)n!=0) { printf("-1 "); return 0; } a[i]=(b[i]+c[i]-sum)/(LL)n; } for(int i=1;i<=n;i++) for(int j=0;j<=62;j++) if(a[i]&g[j]) t[j]++; bool fail=0; for(int i=1;i<=n;i++) { long long sum=0; for(int j=0;j<=62;j++) if(a[i]&g[j]) sum=sum+t[j]*g[j]; if(sum!=b[i]) fail=1; sum=0; for(int j=0;j<=62;j++) { if(a[i]&g[j]) sum=sum+n*g[j]; else sum=sum+t[j]*g[j]; } if(sum!=c[i]) fail=1; } if(fail==0) { for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl; } else cout<<"-1"<<endl; return 0; }