There are two sequences of length n−1n-1n−1, b=(b2,b3,…,bn)b=(b_2,b_3,\ldots,b_n)b=(b2,b3,…,bn), c=(c2,c3,…,cn)c=(c_2,c_3,\ldots,c_n)c=(c2,c3,…,cn). Here, each bib_ibi,cic_ici is a non-negative integer.
Now, the sequence a=(a1,a2,…,an)a=(a_1,a_2,\ldots,a_n)a=(a1,a2,…,an) considers beautiful if and only if forall iii (2≤i≤n)(2 \leq i \leq n)(2≤i≤n), bi=ai−1 or aib_i = a_{i-1} \, \text{or} \, a_{i}bi=ai−1orai, ci=ai−1+aic_i = a_{i-1} + a_{i}ci=ai−1+ai and each aia_iai is a non-negative integer.
Now, Toilet-Ares asks you to calculate the number of beautiful sequences.
The first line contains one integer nnn (2≤n≤105)(2 \leq n \leq 10^5)(2≤n≤105) - the length of sequence aaa. The second line contains n−1n-1n−1 integers b2,b3,…,bnb_2,b_3,\ldots,b_nb2,b3,…,bn (0≤bi<230)(0 \leq b_i < 2^{30})(0≤bi<230) - the elements of sequence bbb. The third line contains n−1n-1n−1 integers c2,c3,…,cnc_2,c_3,\ldots,c_nc2,c3,…,cn (0≤ci<231)(0 \leq c_i < 2^{31})(0≤ci<231) - the elements of sequence ccc.
Print one number - the number of beautiful sequences.
给你一个n和两个数组b和c
你需要输出数组a的种类个数 其中a[i]+a[i+1]=c[i+1], a[i]ora[i+1]=b[i+1]
首先需要知道这样一个性质:
x+y=x|y+x&y
那么c[i] = a[i]+a[i-1] = a[i] | a[i-1] +a[i] & a[i-1]=b[i] + a[i] & a[i-1]
c[i] - b[i]=a[i] & a[i-1];①
b[i] =a[i] | a[i-1] ; ②
由①可知每个c[i] 必须大于b[i],否则直接输出ans=0
由题意可知当确定a【1】时整个a序列都会被确定
那么我们可以枚举a1然后去判断该a1能否符合题意 若符合ans++
这样的时间复杂度是 O(2^31*n)明显不行
那么我们考虑另外一种更优的计算方式
容易发现对于如果每一位分别单独进行计算
假设当前是k位
在一开始由①②两个式子确定a1在k位的可能值 然后进行逐位进行更新ai和ai+1 判断是否可行
如果第k位a[1] | a[2]=1 而且a[1] & a[2] =0 那么意味这a1在第k位有两种选择情况 否则只有一种选择
在k位时若有x种情况最终可行 就让ans*=x
如果有0种可行 则直接输出ans=0
代码注释得很清楚
代码
#include
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
typedef pair PII;
int n,b[maxn];
int c[maxn];
int a[maxn];
int flag=1;
int nd[maxn];
int sol(int a1,int a2,int i)
{
int time=1;
for(int j=2;j<=n;j++)//先判断第一种情况
{
int annow=((c[j]-b[j])>>(i-1))&1;//计算出a[j-1] & a[j] 在第i位的01情况
int ornow=((b[j])>>(i-1))&1;// 计算出a[j-1] | a[j] 在第i位的01情况
if(int(a1&a2)!=annow||int(a1|a2)!=ornow)//不符合情况
{
time--;
break;
}
if(j==n)continue;
int annex=((c[j+1]-b[j+1])>>(i-1))&1;//计算出a[j+1] & a[j] 在第i位的01情况
int ornex=((b[j+1])>>(i-1))&1;// 计算出a[j+1] | a[j] 在第i位的01情况
if(annex)//该位and是1
{
if(ornex)
{
if(a2==1)a1=a2,a2=1;//如果下一个&和|都是1说明 a[j+1] a[j]都得是1
else //如果a[j]已经不是1了 说明不符合题意
{
time--;
break;
}
}
else //如果下一个 &是1 |是0 不符合题意
{
time--;
break;
}
}
else
{
if(ornex)//如果下一个&是0 |是1 说明 a[j+1] a[j]有一个是1 看当前a【j】的情况
{
if(a2==1)a1=a2,a2=0;
else a1=0,a2=1;
}
else //如果下一个&和|都是0说明 a[j+1] a[j]都得是0
{
if(a2==1)
{
time--;
break;
}
else a1=a2=0;
}
}
}
//cout<