2021牛客暑期多校训练营8 D. OR
题意:给你长度为n-1的数列b和c,问有多少种合法的a使得b[i]=a[i-1]|a[i],c[i]=a[i-1]+a[i]
首先我们有x&y + x|y = x+y
(记得NOIP初赛考过这个,当时还不知道
那么相当于我们有了a数列每两项之间的and以及or关系,
这个条件比相加好用很多,套路地拆位考虑就行
#include <bits/stdc++.h>
#define int long long
using namespace std;
int rd(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10+c-'0',c=getchar();
return ret*f;
}
const int MAXN = 100005;
int n;
int b[MAXN],d[MAXN];
int f[MAXN][2];
signed main(){
n=rd();
for(int i=2;i<=n;i++)
b[i]=rd();
for(int i=2;i<=n;i++)
d[i]=rd()-b[i];
int ans=1;
for(int k=30;k>=0;k--){
memset(f,0,sizeof(f));
f[1][0]=f[1][1]=1;
int tmp=(1<<k);
for(int i=2;i<=n;i++){
bool u=(tmp&b[i]),v=(tmp&d[i]);
if(u==0&&v==0){
f[i][0]=f[i-1][0];
f[i][1]=0;
}else if(u==1&&v==0){
f[i][0]=f[i-1][1];
f[i][1]=f[i-1][0];
}else if(u==0&&v==1){
f[i][0]=0;
f[i][1]=0;
}else{
f[i][1]=f[i-1][1];
f[i][0]=0;
}
}
ans*=(f[n][0]+f[n][1]);
}
cout<<ans;
return 0;
}
本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/15120113.html