LuoguP4462 [CQOI2018]异或序列
LuoguP4462 [CQOI2018]异或序列
题面
题解
异或的逆运算就是其本身
即a xor b = c 即 c xor a = b
对于本题,
记录一下1-i的异或和为sum[i]
显然L~R的异或和就为sum[L-1] xor sum[R]
若为异或和为K即满足sum[R] xor K = sum[L-1]
开个桶,莫队即可
注意一下莫队处理时删除一个数时的顺序就好了
#include<bits/stdc++.h> using namespace std; #define LL long long inline LL read() { LL f = 1,x = 0; char ch; do { ch = getchar(); if(ch == '-') f=-1; }while(ch<'0'||ch>'9'); do { x = (x<<3) + (x<<1) + ch - '0'; ch = getchar(); }while(ch>='0'&&ch<='9'); return f*x; } const int MAXN = 100000 + 10; struct Query { int l; int r; int id; }q[MAXN]; int n,m,k,sz; int a[MAXN],sum[MAXN]; int bol[MAXN]; int ans[MAXN]; int cnt[MAXN]; inline bool cmp(Query a1,Query a2) { return (bol[a1.l]^bol[a2.l])?bol[a1.l]<bol[a2.l]:(bol[a1.l]&1)?a1.r<a2.r:a1.r>a2.r; } int main() { n = read();m=read();k=read(); sz = sqrt(2*n/3); for(int i=1;i<=n;i++) a[i]=read(),bol[i]=(i-1)/sz+1; for(int i=1;i<=n;i++) sum[i]=sum[i-1]^a[i]; for(int i=1;i<=m;i++) { q[i].id = i; q[i].l = read() - 1; q[i].r = read(); } sort(q+1,q+m+1,cmp); int l = 1,r = 0; int res = 0; for(int i=1;i<=m;i++) { while(r<q[i].r) r++,res+=cnt[sum[r]^k],cnt[sum[r]]++; while(r>q[i].r) cnt[sum[r]]--,res-=cnt[sum[r]^k],r--; while(l<q[i].l) cnt[sum[l]]--,res-=cnt[sum[l]^k],l++; while(l>q[i].l) l--,res+=cnt[sum[l]^k],cnt[sum[l]]++; ans[q[i].id] = res; } for(int i=1;i<=m;i++) { cout<<ans[i]<<endl; } }