一道稍微要點腦子的莫隊題,原來省選也會搬CF原題git
首先利用\(xor\)的性質,咱們能夠搞一個異或前綴和的東西數組
每一次插入一個數,考慮它和以前已經加入的數能產生多少貢獻spa
記一下以前的異或總值,而後仍是利用異或的性質再異或一遍code
這個咱們再開一個數組統計一下前綴亦或值的出現次數。it
可是惟一要注意的就是一些細節問題,尤爲是左端點加入(or刪除)的時候要減一(搞前綴和的時候左端點確定要減一的麼)io
而後就能夠水過了(個人代碼莫隊的時候寫的有點騷)class
CODE統計
#include<cstdio> #include<cctype> #include<cmath> #include<algorithm> using namespace std; const int N=100005; struct data { int l,r,id; long long ans; }q[N]; int a[N],n,m,k,size,tot,blk[N],L,R,sum[N],cnt[N<<1]={1}; long long res; inline char tc(void) { static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(int &x) { x=0; char ch; while (!isdigit(ch=tc())); while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); } inline void write(int x) { if (x>9) write(x/10); putchar(x%10+'0'); } inline bool cmp1(data a,data b) { return blk[a.l]<blk[b.l]||(blk[a.l]==blk[b.l]&&(blk[a.l]&1?a.r<b.r:a.r>b.r)); } inline bool cmp2(data a,data b) { return a.id<b.id; } inline void add(int x) { res+=cnt[k^sum[x]]; ++cnt[sum[x]]; } inline void del(int x) { --cnt[sum[x]]; res-=cnt[k^sum[x]]; } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); register int i; read(n); read(m); read(k); size=sqrt(n); for (i=1;i<=n;++i) read(a[i]),blk[i]=(i-1)/size+1,sum[i]=sum[i-1]^a[i]; for (i=1;i<=m;++i) read(q[i].l),read(q[i].r),q[i].id=i; sort(q+1,q+m+1,cmp1); L=1; R=0; for (i=1;i<=m;++i) { while (L>q[i].l) add(--L-1); while (L<q[i].l) del(-1+L++); while (R<q[i].r) add(++R); while (R>q[i].r) del(R--); q[i].ans=res; } for (sort(q+1,q+m+1,cmp2),i=1;i<=m;++i) write(q[i].ans),putchar('\n'); return 0; }