洛谷P2709为例来一个莫队算法的模板:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const ll maxn=5e4+5;
ll a[maxn],cnt[maxn],ans[maxn];
struct node{
ll l,r,id;
}q[maxn];
ll n,m,k,sz,sum;
bool cmp(node a,node b){
if((a.l/sz)!=(b.l/sz))
return a.l<b.l;
return a.r<b.r;
}
void add(int x){
if(x<1||x>k) return;
sum+=2*cnt[x]+1;
cnt[x]++;
}
void del(int x){
if(x<1||x>k) return;
sum-=2*cnt[x]-1;
cnt[x]--;
}
int main(){
cin>>n>>m>>k;
sz=sqrt(n);
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
cin>>q[i].l>>q[i].r;
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
ll L=0,R=0;
for(int i=1;i<=m;i++){
while(R<q[i].r) add(a[R+1]),R++;
while(R>q[i].r) del(a[R]),R--;
while(L<q[i].l) del(a[L]),L++;
while(L>q[i].l) add(a[L-1]),L--;
ans[q[i].id]=sum;
}
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}
再来一道例题:https://codeforces.com/contest/617/problem/E
这里4个特判需要注意变化,因为用的是前缀和
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const ll maxn=1<<20;
ll a[maxn],cnt[maxn],ans[maxn];
struct node{
ll l,r,id;
}q[maxn];
ll n,m,k,sz,sum;
bool cmp(node a,node b){
if((a.l/sz)!=(b.l/sz))
return a.l<b.l;
return a.r<b.r;
}
void add(int x){
sum+=cnt[x^k];
cnt[x]++;
}
void del(int x){
cnt[x]--;
sum-=cnt[x^k];
}
int main(){
cin>>n>>m>>k;
sz=sqrt(n);
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]=a[i]^a[i-1];
}
for(int i=1;i<=m;i++){
cin>>q[i].l>>q[i].r;
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
ll L=1,R=0;
cnt[0]=1;
for(int i=1;i<=m;i++){
while(R<q[i].r) R++,add(a[R]);
while(R>q[i].r) del(a[R]),R--;
while(L<q[i].l) del(a[L-1]),L++;
while(L>q[i].l) L--,add(a[L-1]);
ans[q[i].id]=sum;
}
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}