解题思路
将所有询问
(x,y)
(
x
,
y
)
按
y
y
排序,用一个树状数组维护前个数,使每种花出现的倒数第二个位置为
1
1
,再查询的和即可。
代码:
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
using namespace std;
struct ldx{
int x,y,u;
bool operator < (const ldx p) const{
return y<p.y;
}
}s[1000005];
int ans[1000005];
int shi[1000005];
int sh[1000005];
int p[1000005];
int n,c,m,pans;
struct tree{
int a[1000005];
void add(int num,int x){
if(num==0) return ;
while(num<=n){
a[num]+=x;
num+=num&(-num);
}
}
int ch(int num){
int j=0;
while(num>0){
j+=a[num];
num-=num&(-num);
}
return j;
}
}T;
int main(){
scanf("%d%d%d",&n,&c,&m);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
for(int i=1;i<=m;i++) {scanf("%d%d",&s[i].x,&s[i].y);s[i].u=i;}
sort(s+1,s+m+1);
int now=0;
for(int i=1;i<=m;i++){
while(now<s[i].y){
now++;
T.add(shi[p[now]],-1);
T.add(sh[p[now]],1);
shi[p[now]]=sh[p[now]];
sh[p[now]]=now;
}
ans[s[i].u]=T.ch(s[i].y)-T.ch(s[i].x-1);
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}