原题链接
问有多少种长度为n(<=1e5)的序列a,满足b[i]=a[i-1] or a[i],c[i]=a[i-1]+a[i]。
分析:
利用或运算与加法运算的联系:a|b=(a+b)-(a&b),得到序列d,使得d[i]=a[i-1] and a[i]。
之后结合数组b与d,递推分析每个位的数字可能,即可得到答案。
int b[maxv],c[maxv],d[maxv],tag[maxv][2];
int main(){
int n,t,a,flag=1,temp;
int ans=1;
scanf("%d",&n),ans=1;
for(int i=0;i<32;i++) tag[i][0]=tag[i][1]=1;
for(int i=1;i<=n-1;i++) scanf("%d",&b[i]);
for(int i=1;i<=n-1;i++) scanf("%d",&c[i]),d[i]=c[i]-b[i];
for(int i=1;i<=n-1;i++)
for(int j=0;j<32;j++){
int d1=(d[i]>>j)&1,b1=(b[i]>>j)&1;
if(b1){
if(d1) tag[j][0]=0;
else temp=tag[j][0],tag[j][0]=tag[j][1],tag[j][1]=temp;
}else{
if(d1){printf("0");return 0;}
else tag[j][1]=0;
}
}
for(int j=0;j<32;j++)
if(!tag[j][0]&&!tag[j][1]){printf("0");return 0;}
else ans=ans*(tag[j][0]+tag[j][1]);
printf("%d",ans);
return 0;
}