bzoj 5301: [Cqoi2018]异或序列

蛤?这一年cqoi的题这么水????

这不就是个sb莫队吗


这样写怕是会被打死,,,

注意\(a_x\ XOR a_{x+1}\ XOR\ ...\ a_{y}=s_{x-1}\ XOR\ s_y\),所以问题转化为两个数异或值为k的方案数

所以记录一下当前区间的值域和当前区间的答案就星了。。

// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cmath>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
il int gi(){
    rg int x=0,f=1;rg char ch=getchar();
    while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
const int maxn=100010;
struct ques{int l,r,id;}q[maxn];
int n,m,k,a[maxn],B[maxn],s[maxn],tot[maxn];
long long ans[maxn];
bool operator <(const ques&a,const ques&b){
    if(B[a.l]!=B[b.l])return B[a.l]<B[b.l];
    else if(B[a.l]&1)return a.r<b.r;
    else return a.r>b.r;
}
int main(){
    n=gi(),m=gi(),k=gi();
    for(rg int i=1;i<=n;++i)a[i]=gi();
    B[0]=sqrt(n);for(rg int i=1;i<=n;++i)B[i]=i/B[0];
    for(rg int i=1;i<=m;++i)q[i]=(ques){gi(),gi(),i};
    for(rg int i=1;i<=n;++i)s[i]=s[i-1]^a[i];
    std::sort(q+1,q+m+1);
    int l=1,r=1;long long nowAns=0;
    if(a[1]==k)nowAns=1;
    tot[a[1]]=1;
#define Mid ((L+R)>>1)
    for(rg int i=1;i<=m;++i){
        while(q[i].l<l){
            --l;
            ++tot[s[l]];
            nowAns+=tot[k^s[l-1]];
        }
        while(q[i].r<r){
            --tot[s[r]];
            nowAns-=tot[k^s[r]]+((k^s[r])==s[l-1]);
            --r;
        }
        while(q[i].r>r){
            ++r;
            nowAns+=tot[k^s[r]]+((k^s[r])==s[l-1]);
            ++tot[s[r]];
        }
        while(q[i].l>l){
            nowAns-=tot[k^s[l-1]];
            --tot[s[l]];
            ++l;
        }
        ans[q[i].id]=nowAns;
    }
    for(rg int i=1;i<=m;++i)printf("%lld\n",ans[i]);
    return 0;
}
posted @ 2018-04-20 15:01  菜狗xzz  阅读(221)  评论(0编辑  收藏  举报