5301: [Cqoi2018]异或序列
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 204 Solved: 155
[Submit][Status][Discuss]
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
1 2 3 1
1 4
1 3
2 3
2 4
4 4
Sample Output
4
2
1
2
1
2
1
2
1
题解:改为前缀xor和,然后莫队一下。
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 #include<iostream> 6 7 #define N 100007 8 #define ll long long 9 10 #define Wb putchar(' ') 11 #define We putchar(' ') 12 #define rg register int 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 inline void write(ll x) 22 { 23 if(x<0) putchar('-'),x=-x; 24 if (x==0) putchar(48); 25 int num=0;char c[20]; 26 while(x) c[++num]=(x%10)+48,x/=10; 27 while(num) putchar(c[num--]); 28 } 29 30 int n,m,K,blo; 31 int a[N],bel[N],cnt[N<<1]; 32 ll ans[N]; 33 struct Node 34 { 35 int l,r,id; 36 friend bool operator<(Node x,Node y) 37 { 38 if (bel[x.l]!=bel[y.l]) return bel[x.l]<bel[y.l]; 39 return x.r<y.r; 40 } 41 }Q[N]; 42 43 void solve() 44 { 45 int l=1,r=0;ll res=0; 46 for (int i=1;i<=m;i++) 47 { 48 while(l<Q[i].l-1) 49 cnt[a[l]]--,res-=cnt[K^a[l]],l++; 50 while(l>Q[i].l-1) 51 l--,res+=cnt[K^a[l]],cnt[a[l]]++; 52 while(r<Q[i].r) 53 r++,res+=cnt[K^a[r]],cnt[a[r]]++; 54 while(r>Q[i].r) 55 cnt[a[r]]--,res-=cnt[K^a[r]],r--; 56 ans[Q[i].id]=res; 57 } 58 } 59 int main() 60 { 61 n=read(),m=read(),K=read(),blo=(int)sqrt(n); 62 for (rg i=1;i<=n;i++) a[i]=read()^a[i-1]; 63 for (rg i=1;i<=n;i++) bel[i]=(i-1)/blo+1; 64 for (rg i=1;i<=m;i++) 65 Q[i].l=read(),Q[i].r=read(),Q[i].id=i; 66 sort(Q+1,Q+m+1); 67 solve(); 68 for (rg i=1;i<=m;i++) 69 write(ans[i]),We; 70 }