毒瘤xor-------前缀和+贪心

毒瘤xor

https://ac.nowcoder.com/acm/problem/18979

对于一个区间[L,R],对于X二进制下的每一位,如果第i位1,那么对总和的贡献就是[L,R]中的元素第i位是0的元素个数,反之,所以对于X的每一位i的取值依赖于[L,R]中所有元素该位中0,1的数量,如果1居多,那我们就设置0,得到的总和就会大一点,否则就设置1,前缀和预处理一下即可。

#include <cctype>
#include <cfloat>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <istream>
#include <iterator>
#include <list>
#include <map>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#define ll long long
#define pll pair<long long, long long>
#define P pair<int, int>
#define PP pair<P, P>
#define eps 1e-10
#define PI 3.1415926535898
#define It set<node>::iterator
using namespace std;
inline ll Read() {
    ll num=0;
    char ch=getchar();
    while (!isdigit(ch)) ch=getchar();
    while (isdigit(ch)) {
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num;
}
const int maxn=1e5+10;
int val[maxn][31];
int main() {
    int n=Read();
    for (int j=1; j<=n; j++) {
        ll num=Read();
        for (int i=0; i<=30; i++) {
            val[j][i]=val[j-1][i];
            if ((num>>i)&1) val[j][i]++;
        }
    }
    int m=Read();
    while (m--) {
        int l=Read();
        int r=Read();
        if (l>r) swap(l,r);
        ll ans=0;
        int sum=r-l+1;
        for (int i=0; i<=30; i++) {
            int cnt=val[r][i]-val[l-1][i];
            if (cnt*2>=sum) continue;
            ans|=(1ll<<i);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
全部评论

相关推荐

孤寡孤寡的牛牛很热情:为什么我2本9硕投了很多,都是简历或者挂,难道那个恶心人的测评真的得认真做吗
点赞 评论 收藏
分享
09-27 00:29
东北大学 Java
伟大的麻辣烫:查看图片
阿里巴巴稳定性 75人发布 投递阿里巴巴等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务