题目链接:http://codeforces.com/problemset/problem/617/E
一看这种区间查询的题目,考虑一下莫队。
如何${O(1)}$的修改和查询呢?
令${f(i,j)}$表示区间${\left [ l,r \right ]}$内数字的异或和。
那么:${f(l,r)=f(1,r)~~xor~~f(1,l-1)=k}$
记一下前缀异或和即可维护。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 3001000 10 #define llg long long 11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 12 llg n,m,a[maxn],ans,L,R,Ans[maxn],c[maxn],SIZE,k,qzxor[maxn]; 13 struct node 14 { 15 llg l,r,num; 16 }ask[maxn]; 17 18 inline int getint() 19 { 20 int w=0,q=0; char c=getchar(); 21 while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar(); if(c==‘-‘) q=1,c=getchar(); 22 while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar(); return q ? -w : w; 23 } 24 25 bool cmp(const node&a,const node&b) 26 { 27 if (a.l/SIZE==b.l/SIZE) return a.r<b.r; 28 return a.l/SIZE<b.l/SIZE; 29 } 30 31 void inc(llg x,llg val) {if (x==0 || x>n) return ;ans+=c[val^k],c[val]++;} 32 void dec(llg x,llg val) {if (x==0 || x>n) return ; c[val]--; ans-=c[val^k];} 33 34 int main() 35 { 36 yyj("xor"); 37 cin>>n>>m>>k; 38 for (llg i=1;i<=n;i++) a[i]=getint(),qzxor[i]=qzxor[i-1]^a[i]; 39 for (llg i=1;i<=m;i++) ask[i].l=getint(),ask[i].r=getint(),ask[i].num=i; 40 SIZE=sqrt(n); 41 sort(ask+1,ask+m+1,cmp); 42 c[0]=1; 43 for (llg i=1;i<=m;i++) 44 { 45 llg l=ask[i].l,r=ask[i].r; 46 if (L>l) for (llg i=L-1;i>=l;i--) inc(i,qzxor[i-1]); 47 if (r>R) for (llg i=R+1;i<=r;i++) inc(i,qzxor[i]); 48 if (L<l) for (llg i=L;i<l;i++) dec(i,qzxor[i-1]); 49 if (r<R) for (llg i=R;i>r;i--) dec(i,qzxor[i]); 50 Ans[ask[i].num]=ans; 51 L=l,R=r; 52 } 53 for (llg i=1;i<=m;i++) printf("%lld ",Ans[i]); 54 return 0; 55 }
Codeforces 617 E. XOR and Favorite Number
原文:http://www.cnblogs.com/Dragon-Light/p/6569010.html