对于一个区间[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; }