1. 程式人生 > >【BZOJ5301】【CQOI2018】異或序列(莫隊)

【BZOJ5301】【CQOI2018】異或序列(莫隊)

script oid -i 莫隊 void for per printf main

【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; }

【BZOJ5301】【CQOI2018】異或序列(莫隊)