CF1615B 题解

Codeforces 1615B And It’s Non-Zero 题解

题目传送门:

洛谷
CF

思路

暴力思路

要让所有元素按位与的结果不为 0 0 0,就要让所有元素在二进制的某一位都为 1 1 1

所以我们可以枚举每个二进制位,看看有几个 0 0 0,求出最小值就是答案。

目前代码:

云剪贴板。当我提交的时候,发现提交记录,全 T 了。

优化

我们先来看看为什么会这样:这个算法的时间复杂度是 O ( ∑ r − l + 1 ) O(\sum r - l + 1) O(rl+1)。对于数据来说,已经到了 2 × 1 0 9 2 \times 10^9 2×109 量级,当然会 TLE。我们想到:求的其实是多个区间和的最小值。一想到区间和,就想到用到前缀和。所以,我们可以用 s u m i , j sum_{i,j} sumi,j 表示 1 ∼ i 1 \sim i 1i 中二进制的第 j j j 位上有几个 1 1 1。先预处理一下,算出前缀和数组,最后计算的时候只需要枚举每一个二进制位,时间复杂度是 O ( t ) O(t) O(t)

最终代码:

#include <iostream>
#include <algorithm>
using namespace std;

int sum[200010][20];//前缀和数组,最大为log(2e5)=18
int main (){
    for (int i = 1; i <= 2e5; i++){
        int a[20] = {};//a[i]表示二进制的第i位
        int t = i , cnt = 0;
        while (t){
            a[++cnt] = t & 1;
            t = t >> 1;
        }
        for (int j = 1; j <= cnt; j ++)sum[i][j] = sum[i-1][j] + a[j];
    }
    int t;
    cin >> t;
    while (t--){
        int l , r;
        cin >> l >> r;
        int mx = 0;
        for (int i = 1; i <= 20; i ++)//枚举每一个二进制位
            mx = max(mx , sum[r][i] - sum[l-1][i]);
        cout << r - l + 1 - mx << endl;//通过0的个数求1的个数
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值