版权声明:虽然博主很菜,但是还是请注明出处(我觉得应该没人偷我的博客) https://blog.csdn.net/qq_43346903/article/details/87875148
表示
异或起来的值
异或有性质:
证明就是异或可以相互抵消
(树上也有类似的性质,
)
然后不就变成莫队模板题了(CQOI2018都是些什么东西,考了模板X3)
位运算打括号
Code:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
const int N=1e5+5;
int n,m,k,sqr;
int a[N],sum[N],ans[N],tot,cnt[N];
struct Q{int l,r,id,bel;}q[N];
inline bool cmp(Q a,Q b){
if(a.bel==b.bel) return a.r<b.r;
return a.bel<b.bel;
}
int main(){
n=read();m=read();k=read(),sqr=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=m;i++){
q[i].l=read(),q[i].r=read();
q[i].id=i;q[i].bel=(q[i].l-1)/sqr+1;
}
sum[1]=a[1];
for(int i=2;i<=n;i++) sum[i]=sum[i-1]^a[i];
sort(q+1,q+m+1,cmp);
int l=1,r=0;
for(int i=1;i<=m;i++){
while(r<q[i].r){
cnt[sum[++r]]++,tot+=cnt[sum[r]^k];
if((sum[r]^k)==sum[l-1]) ++tot;
}
while(r>q[i].r){
tot-=cnt[sum[r]^k],cnt[sum[r]]--;
if((sum[r--]^k)==sum[l-1]) --tot;
}
while(l<q[i].l) tot-=cnt[sum[l-1]^k],cnt[sum[l++]]--;
while(l>q[i].l) cnt[sum[--l]]++,tot+=cnt[sum[l-1]^k];
ans[q[i].id]=tot;
}
for(int i=1;i<=m;i++) cout<<ans[i]<<"\n";
return 0;
}