【题解】[codeforces 617E] XOR and Favorite Number【莫队】

题目链接

题意

给定序列 (a),非负整数 (k)(m) 次询问:([l,r]) 内有多少子区间的异或和为 (k)(n,mleq 10^5)

题解

莫队。用一个桶记录当前区间内值为 (i) 的数的数量,移动指针时加减对应的数即可。

#include<bits/stdc++.h>
using namespace std;
int getint(){
    int ans=0;
    char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){
        ans=ans*10+c-'0';
        c=getchar();
    }
    return ans;
}
const int N=1e5+10,M=1<<20;
#define ll long long
struct query{
    int l,r,id;
};
query q[N];
int a[N],c[M];
int n,m,k,b;

bool cmp(const query &x,const query &y){
    if(x.l/b!=y.l/b)return x.l/b<y.l/b;
    return (x.r/b<y.r/b);
}

ll ans[N];
int main(){
    n=getint(),m=getint(),k=getint();
    b=sqrt(n)+1;
    for(int i=1;i<=n;i++)a[i]=getint()^a[i-1];
    for(int i=0;i<m;i++)
        q[i].l=getint()-1,q[i].r=getint(),q[i].id=i;
    sort(q,q+m,cmp);
    int l=1,r=0;
    ll ans=0;
    for(int i=0;i<m;i++){
        while(r>q[i].r){
            c[a[r]]--;
            ans-=c[a[r]^k];
            --r;
        }
        while(r<q[i].r){
            ++r;
            ans+=c[a[r]^k];
            c[a[r]]++;
        }
        while(l<q[i].l){
            c[a[l]]--;
            ans-=c[a[l]^k];
            ++l;
        }
        while(l>q[i].l){
            --l;
            ans+=c[a[l]^k];
            c[a[l]]++;
        }
        ::ans[q[i].id]=ans;
    }
    for(int i=0;i<m;i++)printf("%lld
",::ans[i]);
    return 0;
}
知识共享许可协议
若文章内无特别说明,公开文章采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
原文地址:https://www.cnblogs.com/wallbreaker5th/p/13935374.html