【BZOJ5301】【CQOI2018】异或序列(莫队)

题面

BZOJ
洛谷

Description

已知一个长度为 n 的整数数列 a[1],a[2],…,a[n] ,给定查询参数 l、r ,问在 [l,r] 区间内,有多少连续子
序列满足异或和等于 k 。
也就是说,对于所有的 x,y (l≤x≤y≤r),能够满足a[x]^a[x+1]^…^a[y]=k的x,y有多少组。

Input

输入文件第一行,为3个整数n,m,k。
第二行为空格分开的n个整数,即ai,a2,….an。
接下来m行,每行两个整数lj,rj,表示一次查询。
1≤n,m≤105,O≤k,ai≤105,1≤lj≤rj≤n

Output

输出文件共m行,对应每个查询的计算结果。

Sample Input

4 5 1

1 2 3 1

1 4

1 3

2 3

2 4

4 4

Sample Output

4

2

1

2

1

题解

板子题+原题
我也没有什么好说的了。
果然是模板大赛啊。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 111111
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
ll ans[MAX],Ans;
int n,m,K,blk,num[MAX],a[MAX];
struct Query{int l,r,id,lb;}q[MAX];
bool operator<(Query a,Query b){if(a.lb!=b.lb)return a.lb<b.lb;return a.r<b.r;}
void Add(int x){Ans+=num[K^a[x]],++num[a[x]];}
void Del(int x){--num[a[x]],Ans-=num[K^a[x]];}
int main()
{
    n=read();m=read();K=read();blk=sqrt(n);
    for(int i=1;i<=n;++i)a[i]=read()^a[i-1];
    for(int i=1;i<=m;++i)
    {
        int l=read(),r=read();
        q[i]=(Query){l-1,r,i,l/blk};
    }
    sort(&q[1],&q[m+1]);
    int L=0,R=-1;
    for(int i=1;i<=m;++i)
    {
        while(R<q[i].r)Add(++R);
        while(L>q[i].l)Add(--L);
        while(L<q[i].l)Del(L++);
        while(R>q[i].r)Del(R--);
        ans[q[i].id]=Ans;
    }
    for(int i=1;i<=m;++i)printf("%lld\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_30974369/article/details/80029147