BZOJ5301: [Cqoi2018]異或序列(莫隊)
阿新 • • 發佈:2018-11-15
5301: [Cqoi2018]異或序列
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 400 Solved: 291
[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
Output
輸出檔案共m行,對應每個查詢的計算結果。Sample Input
4 5 11 2 3 1
1 4
1 3
2 3
2 4
4 4
Sample Output
42
1
2
1
沒什麼說的,注意右區間操作時,要考慮左邊的字首。
#include<bits/stdc++.h> usingnamespace std; const int maxn=100010; struct in{int l,r,g,id;}s[maxn]; bool cmp(in w,in v){if(w.g!=v.g) return w.g<v.g; return w.r<v.r;} int sum[maxn],cnt[maxn]; long long ans[maxn]; int main() { int N,M,K,L,R,B,res; scanf("%d%d%d",&N,&M,&K); B=sqrt(N); for(int i=1;i<=N;i++) scanf("%d",&sum[i]),sum[i]^=sum[i-1]; L=1; R=res=0; for(int i=1;i<=M;i++){ scanf("%d%d",&s[i].l,&s[i].r); s[i].id=i; s[i].g=s[i].l/B; } sort(s+1,s+M+1,cmp); for(int i=1;i<=M;i++) { while(R<s[i].r) cnt[sum[++R]]++,res+=cnt[sum[R]^K]+((sum[R]^K)==sum[L-1]); while(R>s[i].r) res-=cnt[sum[R]^K]+((sum[R]^K)==sum[L-1]),cnt[sum[R--]]--; while(L<s[i].l) res-=cnt[sum[L-1]^K],cnt[sum[L++]]--; while(L>s[i].l) cnt[sum[--L]]++,res+=cnt[sum[L-1]^K]; ans[s[i].id]=res; } for(int i=1;i<=M;i++) printf("%lld\n",ans[i]); return 0; }