nowcoder35B 小AA的数列

题意:一个序列问长度为偶数且在[L, R]范围内的异或和的和

题解:首先要知道这个题的简化版,也就是所有区间异或和的和,可以计算每一位的贡献乘以权重就是答案,求一位的所有异或和的和只要计算异或和是1的个数就可以,也就是xor[l, r] == 1,那么前缀xorsum[r]^xorsum[l-1] == 1,xorsum[r] == xorsum[l-1]^1也就是计算每一个数前面有多少个满足xorsum[r] == xorsum[l-1]^1,用数组标记一下就可以计算,那么这道题有两个限制,只要在更新的过程中加上两个限制就可以

#include <bits/stdc++.h>
#define maxn 200010
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
ll dir[2][2], n, l, r, a[maxn];
ll check(ll l,ll r){
    ll sum = 0, ans;
    for(ll i=0;i<31;i++){
        ans = 0;
        memset(dir, 0, sizeof(dir));
        for(ll j=1;j<=n;j++){
            if(j>=l) dir[(j-l)&1][(a[j-l]>>i)&1]++;
            ans = (ans+dir[j&1][!((a[j]>>i)&1)])%mod;
            if(j>=r) dir[(j-r)&1][(a[j-r]>>i)&1]--;
        }
        sum = (sum+ans*(1LL<<i)%mod)%mod;
    }
    return (sum+mod)%mod;
}
int main(){
    cin>>n>>l>>r;
    if(l&1) l++;
    if(r&1) r--;
    if(l>r){
        printf("0
");
        return 0;
    }
    for(ll i=1;i<=n;i++) cin>>a[i];
    for(ll i=1;i<=n;i++) a[i] = a[i-1]^a[i];
    cout<<(check(l, r)+mod)%mod<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/7894917.html