CF1615B 题解

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

题目传送门:

洛谷
CF

思路

暴力思路

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

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

目前代码:

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

优化

我们先来看看为什么会这样:这个算法的时间复杂度是 \(O(\sum r - l + 1)\)。对于数据来说,已经到了 \(2 \times 10^9\) 量级,当然会 TLE。我们想到:求的其实是多个区间和的最小值。一想到区间和,就想到用到前缀和。所以,我们可以用 \(sum_{i,j}\) 表示 \(1 \sim i\) 中二进制的第 \(j\) 位上有几个 \(1\)。先预处理一下,算出前缀和数组,最后计算的时候只需要枚举每一个二进制位,时间复杂度是 \(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的个数
    }
}
posted @ 2026-01-21 19:50  aaalys  阅读(12)  评论(0)    收藏  举报
//雪花飘落效果