我对莫队算法最为纠结的地方就是区间端点处,应该是像代码里那样理解吧
cnt[i]表示i出现的次数
maxn开2e6比较保险
/*H E A D*/
struct Query{
int l,r,id;
}q[maxn];
int size;
bool cmp(Query a,Query b){
if(a.l/size!=b.l/size) return a.l/size<b.l/size;
else return a.r<b.r;
}
ll cnt[maxn],a[maxn];
ll ans[maxn];
int main(){
int n,m,k;
while(cin>>n>>m>>k){
memset(cnt,0,sizeof cnt);
rep(i,1,n) a[i]=read();
rep(i,2,n) a[i]^=a[i-1];
rep(i,1,m){
q[i].l=read();
q[i].r=read();
q[i].id=i;
}
size=sqrt(n);
sort(q+1,q+1+m,cmp);
int l=1,r=0;//l-1=0 r=0
cnt[0]++;
ll tmp=0;
rep(i,1,m){
while(l<q[i].l){//删去[l,q[i].l-1]
cnt[a[l-1]]--;
tmp-=cnt[a[l-1]^k];
l++;
}
while(l>q[i].l){//添加[q[i].l,l-1]
tmp+=cnt[a[l-2]^k];//l-1-1
cnt[a[l-2]]++;
l--;
}
while(r<q[i].r){//增加[r+1,q[i].r]
tmp+=cnt[a[r+1]^k];
cnt[a[r+1]]++;
r++;
}
while(r>q[i].r){//删去[q[i].r+1,r]
cnt[a[r]]--;
tmp-=cnt[a[r]^k];
r--;
}
ans[q[i].id]=tmp;
}
rep(i,1,m) println(ans[i]);
}
return 0;
}
原文地址:https://www.cnblogs.com/caturra/p/8428609.html
时间: 2024-10-08 05:11:19