Codeforces Global Round 18 B. And It's Non-Zero(按位前缀和)

题目大意:求一段数(l到r)的按位与结果不为零需要删除中间元素的最小个数

思路:按位与使得结果不为0只要有某一位全是1即可,所以只要统计每一位1的个数,用总个数减去1的个数就是某一位0的个数

删除包含0最少的那一位就是最少需要删除的个数

 1 # include<iostream>
 2 # include<bits/stdc++.h>
 3 using namespace std;
 4 # define int long long
 5 # define endl "\n"
 6 const int N = 2e5 + 10;
 7 int a[20][N];
 8 void solve()
 9 {
10    int l,r;
11    cin>>l>>r;
12    int ans = 200005;
13    for(int j = 0;j < 20;++j){
14            ans= min(ans,r-l+1-(a[j][r]-a[j][l-1]));
15    }
16    cout<<ans<<endl;
17 }
18 int tt;
19 signed main() {
20     ios::sync_with_stdio(false);
21     cin.tie(0);
22     cout.tie(0);
23     
24     for(int i = 1;i <= 200000;++i){
25         bitset<20> b(i);
26         for(int j = 0;j< 20;++j) a[j][i] = b[j];
27     }
28     for(int j = 0;j < 20;++j)
29         for(int i  = 1;i <= 200000;++i){
30             a[j][i] += a[j][i-1];    
31         }
32     
33     
34     cin >> tt;
35     while (tt--)solve();
36  
37  
38     return 0;
39 }

用bitset预处理出每一位1的个数,前缀和统计

bitset<20>(i) 数字i的20位二进制表示

posted @ 2022-08-06 17:43  empty_y  阅读(40)  评论(0)    收藏  举报