2021牛客暑期多校训练营#8:D-OR
原题链接:https://ac.nowcoder.com/acm/contest/11259/K
题目大意
给定两个长度为
n
−
1
n-1
n−1的非负整数序列
b
=
(
b
2
,
b
3
,
…
,
b
n
)
,
c
=
(
c
2
,
c
3
,
…
,
c
n
)
b=(b_2,b_3,\ldots,b_n),c=(c_2,c_3,\ldots,c_n)
b=(b2,b3,…,bn),c=(c2,c3,…,cn)。求满足以下条件的非负整数序列
a
a
a的数量:
−
∀
i
∈
[
2
,
n
]
,
b
i
=
a
i
−
1
∣
a
i
,
c
=
a
i
−
1
+
a
i
;
-\forall i\in[2,n],b_i=a_{i-1}|a_i,c=a_{i-1}+a_i;
−∀i∈[2,n],bi=ai−1∣ai,c=ai−1+ai;
解题思路
由于加法存在烦人的进位操作,所以首先考虑进位的情况:
1.
第
i
位
都
是
1
,
进
位
;
2.
第
i
位
都
是
0
,
不
变
;
3.
第
i
位
一
个
0
一
个
1
,
变
成
1
。
\begin{aligned} &1.第i位都是1,进位;\\ &2.第i位都是0,不变;\\ &3.第i位一个0一个1,变成1。 \end{aligned}
1.第i位都是1,进位;2.第i位都是0,不变;3.第i位一个0一个1,变成1。
而位或运算和位与运算的关系是
1.
第
i
位
都
是
1
,
变
成
1
;
2.
第
i
位
都
是
0
,
是
0
;
3.
第
i
位
一
个
0
一
个
1
,
变
成
1
。
\begin{aligned} &1.第i位都是1,变成1;\\ &2.第i位都是0,是0;\\ &3.第i位一个0一个1,变成1。 \end{aligned}
1.第i位都是1,变成1;2.第i位都是0,是0;3.第i位一个0一个1,变成1。
我们可以发现
c
i
=
a
i
−
1
∣
a
i
+
a
i
−
1
&
a
i
c_i=a_{i-1}|a_i+a_{i-1}\&a_i
ci=ai−1∣ai+ai−1&ai。所以我们只要枚举
a
i
−
1
a_{i-1}
ai−1和
a
i
a_i
ai的位即可。
代码实现
#include<bits/stdc++.h>
using namespace std;
int b[199991],c[199991],a,n,ans=1;
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];
for(int i=0;i<31;i++)
{
int l=1,r=1;
for(int j=2;j<=n;j++)
{
int x=b[j]>>i&1,y=c[j]>>i&1;
int d=0,e=0;
if(x&&y)e=r;
if(x&&!y)d=r,e=l;
if(!x&&!y)d=l;
l=d,r=e;
}
ans*=l+r;
}
cout<<ans;
}