如果我们知道区间[L,R],就能在O(1)求出[L−1,R],[L+1,R],[L,R−1],[L,R+1]的话,那就可以用莫队算法了
就是对在区间之间的查询时常常使用莫队
莫队通常使用的模板:
#include<string.h>
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct question{
int l;
int r;
int id;
}qst[1110000];
int comp(const question & a,const question & b)
{
if(a.l==b.l)
return a.r<b.r;
return a.l<b.l;
}
int sum,num[1110000],l,r,ans[1110000];
void pls(int x)
{
num[x]++;
if(num[x]==1)
sum++;
}
void mns(int x)
{
num[x]--;
if(num[x]==0)
sum--;
}
int str[1111000];
int main()
{
int m,n,k;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&str[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d %d",&qst[i].l,&qst[i].r);
qst[i].id=i;
}
sort(qst+1,qst+m+1,comp);
memset(num,0,sizeof(num));
memset(ans,0,sizeof(ans));
sum=0;
l=0;
r=0;
for(int i=1;i<=m;i++)
{
while(r<qst[i].r){
r++;
pls(str[r]);
}
while(r>qst[i].r){
mns(str[r]);
r--;
}
while(l<qst[i].l){
mns(str[l]);
l++;
}
while(l>qst[i].l){
l--;
pls(str[l]);
}
ans[qst[i].id]=sum;
}
for(int i=1;i<=m;i++)
cout<<ans[i]<<endl;;
return 0;
}