2021牛客暑期多校训练营8_D.OR(赛场上可能出不了,一知半解ing))

这篇文章讲述了如何使用位运算技巧求解一个关于数组a的问题,给定b和c数组,通过分析|和&运算,巧妙地确定a数组的可能构造。博主详细解释了思路并给出了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D.OR

题目传送门:

题目传送门

题面:

在这里插入图片描述

题目大意:

给你n-1个元素的数组 b , c b,c bc
b 2 , b 3 , b 4 . . . b n {b_2,b_3,b_4...b_n} b2,b3,b4...bn以及 c 2 , c 3 , c 4 . . . c n {c_2,c_3,c_4...c_n} c2,c3,c4...cn
已知 b i = a i − 1 ∣ a i b_i=a_i-_1 | a_i bi=ai1ai c i = a i − 1 + a i c_i=a_i-_1+a_i ci=ai1+ai。问你能构造出几组这样的数组a?

思路:

在这里插入图片描述

所以这样的话相当于相邻a数组的|和&都知道了,避免了进位讨论的麻烦。
在这里插入图片描述
这位老哥表格画的特清楚,放着用了。
图源在这里插入图片描述
侵删。
在这里插入图片描述

这句话也很关键。

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 114514;
ll b[maxn], c[maxn];

int main() {
    int n;
    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 = 2; i <= n; i++)
//        cout << b[i] << " ";
//    cout << endl;
//    for (int i = 2; i <= n; i++)
//        cout << c[i] << " ";
    //cout << endl;
    ll ans = 1;
    ///此时数组b存储的是|,c存储了&;
    for (int j = 0; j < 31; j++) {
        /// 枚举a1的每一位
        int a0 = 1, a1 = 1;
        for (int i = 2; i <= n; i++) {
            int x = b[i] >> j & 1;
            int y = c[i] >> j & 1;
            //对b,c当中遍历每一个元素取出第j位
            int b0 = 0, b1 = 0;
            if (x && y) {
                b1 = a1;
                //就是全1啦
                //保持b0=0;
            } else if (x && !y) {
                b1 = a0;
                b0 = a1;
                //就是0和1嘞
            } else if (!x && !y) {
                b0 = a0;
                //保持b1=0;
                //就是全0嘞
            }
            a0 = b0;
            a1 = b1;
            //确定a[1]这一位的状态
            //对取0/1可能性赋值代表前一位对后一位可能的影响。
            //只能说很巧妙...
        }
        ans *= (a0 + a1);
        if (!ans) break;
        //更新答案
        //每一位要么0,1,2三种可能;
        // cout << ans << " ";
    }
    cout << ans << endl;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值