题面:已知b[i]=a[i] | a[i-1], c[i]=a[i]+a[i-1] (i=2....n),求a数组有多少可能。
解析:c[i]=a[i]+a[i-1]=a[i] | a[i-1] + a[i] & a[i-1]。
设d[i]=c[i]-b[i]=a[i] & a[i-1]。知道a[1]就可以确定a数组,接下来只要枚举a[1]即可。
这里因为按位与和按位或,自然采用二进制的方法枚举a[1]的每一位。判断a[i]的每一位是否符合条件。
代码:
#include<bits/stdc++.h> using namespace std; int n; int b[100005],c[100005]; int main(){ cin>>n; for(int i=2;i<=n;i++) cin>>b[i]; for(int i=2;i<=n;i++) cin>>c[i],c[i]-=b[i]; int ans=1; for(int i=0;i<=31;i++){//循环每一位 int bit0=1,bit1=1;//a[1]的第i位取0,1皆可 for(int j=2;j<=n;j++){//循环a[2]到a[n] int nowbit0=0,nowbit1=0;a[j]第i位0,1都不能取 int x=b[j]>>i&1; int y=c[j]>>i&1; if(!x&&!y) nowbit0=bit0;//若同时为0,说明该位和前一位都为0. else if(x&&!y) nowbit1=bit0,nowbit0=bit1; else if(x&&y) nowbit1=bit1; //不存在0,1的情况 bit0=nowbit0,bit1=nowbit1; } ans*=(bit1+bit0); } cout<<ans<<endl; }