题意:给两个长度为n-1的非负序列(b2,b3...bn)(c2,c3...cn),求满足下列条件的a序列有多少个:
1.b[i]=a[i-1]|a[i];2.c[i]=a[i-1]+a[i]
思路:
显然c[i]-b[i]=a[i-1]&a[i](因为a&b+a|b=a+b)
因为对于a序列,a1一旦确定,就能根据c序列确定整个序列,所以我们枚举a1可能的取值就行
具体就是枚举a1的每一位能取0或者1
lasno0=1代表a[j-1]的第i位不能取0,lasno1=1a[j-1]的第i位代表不能取1;
nowno0=1代表a[j]的第i位不能取0,nowno1=1a[j]的第i位代表不能取1;
枚举从2到n,只有始终 &=0并且|=1 时a1的第i位可以取01两种结果(所以判断lasno1,lasno0就能判断是不是需要乘2)
如果出现 &=0,|=1 则不可能有这样的a1
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
int b[N], c[N];
int main()
{
int n;
cin >> n;
for (int i = 2; i <= n; i++)
{
scanf("%d", &b[i]);
}
for (int i = 2; i <= n; i++)
{
scanf("%d", &c[i]);
c[i] -= b[i];
}
int ans = 1;
for (int i = 0; i < 31; i++)
{
int lasno0 = 0, lasno1 = 0;
for (int j = 2; j <= n; j++)
{
int nowno0 = 0, nowno1 = 0;
int And = (c[j] >> i) & 1, Or = (b[j] >> i) & 1;
if (And == 0 && Or == 0)
{
if (lasno0)
{
ans = 0;
break;
}
nowno1 = 1;
}
else if (And == 1 && Or == 1)
{
if (lasno1)
{
ans = 0;
break;
}
nowno0 = 1;
}
else if (And == 1 && Or == 0)
{
ans = 0;
break;
}
else
{
nowno0 = lasno1;
nowno1 = lasno0;
}
lasno0 = nowno0;
lasno1 = nowno1;
//cout<< lascnt << nowcnt << endl;
}
if (ans)
{
if (!lasno1&&!lasno0)//只有一直是01都可以取才有两种可能
{
ans <<= 1;
//cout << ans << endl;
}
}
else
{
break;
}
}
cout << ans << endl;
return 0;
}