思路:
性质题。
(a&b)+(a|b)=a+b。于是可以构造出一组满足这一位满足 $(b[i]+c[i])$ 的唯一一组解,在对于这组解去验证答案是否正确,若不正确则无解。
以下代码:


#include<bits/stdc++.h> #define il inline #define LL long long #define _(d) while(d(isdigit(ch=getchar()))) using namespace std; const int N=2e5+5; int n,b[N],a[N],num[30],c[N],d[N];LL sum; il int read(){ int x,f=1;char ch; _(!)ch=='-'?f=-1:f;x=ch^48; _()x=(x<<1)+(x<<3)+(ch^48); return f*x; } int main() { n=read(); if(n==1){ int x=read(),y=read(); if(x!=y)return puts("-1"),0; else return printf("%d\n",x),0; } for(int i=1;i<=n;i++)b[i]=c[i]=read(); bool pd=0; for(int i=1;i<=n;i++){ int x=read();if(b[i]>x)pd=1; b[i]+=x,sum+=b[i];d[i]=x; } if(pd)return puts("-1"),0; if(sum%(2*n))return puts("-1"),0; sum=sum/(2*n); for(int i=1;i<=n;i++)if((b[i]-sum)%n)return puts("-1"),0; for(int i=1;i<=n;i++)a[i]=(b[i]-sum)/n; for(int i=1;i<=n;i++){ for(int j=0;j<30;j++)if(a[i]&(1<<j))num[j]++; } for(int i=1;i<=n;i++){ int num1=0,num2=0; for(int j=0;j<30;j++){ if(a[i]&(1<<j))num1+=1ll*num[j]*(1<<j),num2+=1ll*n*(1<<j); else num1+=0,num2+=1ll*num[j]*(1<<j); } if(num1!=c[i]||num2!=d[i])return puts("-1"),0; } for(int i=1;i<=n;i++)printf("%d ",a[i]); return 0; }
本文探讨了一种基于位运算的算法题目解决思路,通过构造特定的数学模型,利用位运算的特性,如与(&)、或(|)操作,来求解一组数的唯一解。通过对给定条件的分析,验证解的存在性和正确性,最终实现了一种高效求解算法。
183

被折叠的 条评论
为什么被折叠?



