0
点赞
收藏
分享

微信扫一扫

2021牛客暑期多校训练营8 - D(OR)

补题链接:​​https://ac.nowcoder.com/acm/contest/11259/D​​

作此题需要的前导知识: 2021牛客暑期多校训练营8 - D(OR)_多校 = 2021牛客暑期多校训练营8 - D(OR)_数组_02 + 2021牛客暑期多校训练营8 - D(OR)_位运算_03
而题中给出: 2021牛客暑期多校训练营8 - D(OR)_多校_04 = 2021牛客暑期多校训练营8 - D(OR)_数组_052021牛客暑期多校训练营8 - D(OR)_数组_06 = 2021牛客暑期多校训练营8 - D(OR)_位运算_07
所以设 2021牛客暑期多校训练营8 - D(OR)_多校_08 = 2021牛客暑期多校训练营8 - D(OR)_多校_09 = 2021牛客暑期多校训练营8 - D(OR)_i++_10
此时有 2021牛客暑期多校训练营8 - D(OR)_多校_04 = 2021牛客暑期多校训练营8 - D(OR)_位运算_122021牛客暑期多校训练营8 - D(OR)_多校_08 = 2021牛客暑期多校训练营8 - D(OR)_i++_10

所以此时对于2021牛客暑期多校训练营8 - D(OR)_多校_15的每一位我们可以分开考虑(它只与当前位有关),
所以我们可以枚举2021牛客暑期多校训练营8 - D(OR)_补题_16的每一位(不是1就是0),
设初始2021牛客暑期多校训练营8 - D(OR)_多校_17
如果(2021牛客暑期多校训练营8 - D(OR)_补题_16的当前位取1或着0)推出 2021牛客暑期多校训练营8 - D(OR)_i++_19,2021牛客暑期多校训练营8 - D(OR)_补题_20,…,2021牛客暑期多校训练营8 - D(OR)_位运算_21, (0或着1)只有一个满足 2021牛客暑期多校训练营8 - D(OR)_数组_22,2021牛客暑期多校训练营8 - D(OR)_数组_23,…,2021牛客暑期多校训练营8 - D(OR)_多校_24,和 2021牛客暑期多校训练营8 - D(OR)_补题_25,2021牛客暑期多校训练营8 - D(OR)_补题_26,…,2021牛客暑期多校训练营8 - D(OR)_补题_27说明当前位只有一种选择,2021牛客暑期多校训练营8 - D(OR)_位运算_28
如果(0或者1)都满足则2021牛客暑期多校训练营8 - D(OR)_位运算_29
如果(0或者1)都不满足,则2021牛客暑期多校训练营8 - D(OR)_i++_30
(相当于判断二进制数的每一位有多少种选择,然后推出 2021牛客暑期多校训练营8 - D(OR)_数组_31 进制的数有多少个)

​AC code​

#include<iostream>

using namespace std;
const int N = 1e5 + 10;
typedef long long ll;

int a[N], b[N], c[N], d[N];
int n;

bool check(int idx, int x){

int v[n + 1]; // 记录ai的当前idx位的值
v[1] = x;
for(int i = 2; i <= n; i++){

// 获取b数组的第i个数的idx位和d数组的第i个数的idx位
int nd = (d[i] >> idx) & 1, nb = (b[i] >> idx) & 1;

// ai-1 & ai == 1
if(nd){
// ai-1 | ai == 1
if(nb){

if(v[i - 1]){
// 两个数 & 为1,两个数 | 为1,两个数一定都为1
v[i] = 1;
}else{
// 如果v[i-1]为0,则不满足
return 0;
}
}else{ // ai-1 | ai == 0
// &为1, | 为0,矛盾
return 0;
}
}else{ // ai-1 & ai == 0
// ai-1 | ai == 1
if(nb){ // 与为0,或为1,则一个为0,一个为1

if(v[i - 1]) v[i] = 0;
else v[i] = 1;

}else{// ai-1 | ai == 0
// 两个只能都为0
if(v[i - 1]) return 0;
v[i] = 0;
}

}

}

return 1;
}

int main(){

scanf("%d", &n);

for(int i = 2; i <= n; i++){

scanf("%d", &b[i]);
}

for(int i = 2; i <= n; i++){

scanf("%d", &c[i]);
}

for(int i = 2; i <= n; i++){

d[i] = c[i] - b[i];
}

ll ans = 1;

// 枚举a1的每一位,判断对于每个 d 的相应位,是否满足
for(int i = 0; i < 30; i++){

ans *= (check(i, 0) + check(i, 1));

}

printf("%lld\n", ans);

return 0;
}


举报

相关推荐

0 条评论