题意

小AA找到了一个数列,她想要知道这个数列中所有长度为偶数的区间异或和之和 。
后来她发现这个问题太简单了,于是她加了一个限制,要求区间长度在[L,R]之间,
然后她就不会了。。。
请你告诉她问题的答案。
其中,

分析

和位运算有关的题统统按位考虑=。=,于是我们枚举二进制的每一位。
问题转化为:有 个数,每个数为 ,求偶数长度且长度在 且区间和为奇数的区间数量。(真tm绕)
如果区间和为奇数,意味着 。于是我们只关心前缀和的奇偶性。
这样子问题又转化另一个问题:求 中与 不同的数的个数。这个可以用一个前缀和快速求出。
然后由于区间长度为偶数,我们要对奇偶分别开一个数组记录前缀和。。细节还是挺多的。。
最后复杂度是

代码如下

#include <bits/stdc++.h>
#define N 100005
const int mod = 1e9 + 7;
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
LL z = 1;
int read(){
    int x, f = 1;
    char ch;
    while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
    x = ch - '0';
    while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;
    return x * f;
}
int ksm(int a, int b, int p){
    int s = 1;
    while(b){
        if(b & 1) s = z * s * a % p;
        a = z * a * a % p;
        b >>= 1;
    }
    return s;
}
int a[N], s[N], sum[N][2][2];
int main(){
    int i, j, n, m, l, r, t = 1, ans = 0, tot, x, y;
    n = read(); l = read(); r = read();
    for(i = 1; i <= n; i++) a[i] = read();
    for(i = 0; i <= 30; i++){
        tot = 0;
        for(j = 1; j <= n; j++){
            if(1 << i & a[j]) s[j] = (s[j - 1] + 1) % 2;
            else s[j] = s[j - 1]; 
        }
        sum[0][0][0] = 1;
        for(j = 1; j <= n; j++){
            sum[j][0][0] = sum[j - 1][0][0]; sum[j][0][1] = sum[j - 1][0][1];
            sum[j][1][0] = sum[j - 1][1][0]; sum[j][1][1] = sum[j - 1][1][1];
            if(j >= l){
                x = max(0, j - r); y = j - l;
                if(x >= 1) tot = (tot + sum[y][j & 1][1 - s[j]] - sum[x - 1][j & 1][1 - s[j]]) % mod;
                else tot = (tot + sum[y][j & 1][1 - s[j]]) % mod;
            }
            sum[j][j & 1][s[j]]++;
        }
        ans = (ans + z * t * tot) % mod;
        t = t * 2 % mod;
    }
    printf("%d", (ans + mod) % mod);
    return 0;
}