思路
类似于 HH的项链
本题题意:问区间[L,R]里,出现次数 >= 2 的元素有几种
不同之处在于本题需要维护两个last
last1[i]:i 上一次出现的位置
last2[i]:i 上上次出现的位置
对于一个元素 x ,当它第一次出现时,什么都不发生,同时更新 last1
当它的 last1[x] 存在时,在 last1[x] 位置上 加1,同时更新 last1 和 last2
当它的 last2[x] 存在时,在 last1[x] 位置上 加1, 在 last2[x] 位置上 减1,同时更新 last1 和 last2
即坚守这样一个原则,对于当前枚举到的元素 x,我们只在其上一次出现位置上加 1,至于已经出现的其他位置,我们都保持为 0
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6+10;
int x[N],tr[N];
int last1[N],last2[N],ans[N];
int n,c,m;
struct node{
int id;
int l,r;
bool operator < (const node & x) const{
return r < x.r;
}
}p[N];
int lowbit(int x){
return x & - x;
}
void add(int x,int v){
for(int i=x;i<=N;i+=lowbit(i)) tr[i]+=v;
}
int sum(int x){
int res=0;
for(int i=x;i;i-=lowbit(i)) res+=tr[i];
return res;
}
int main(){
scanf("%d%d%d",&n,&c,&m);
for(int i=1;i<=n;i++) scanf("%d",&x[i]);
for(int i=1;i<=m;i++){
int l,r;
scanf("%d%d",&l,&r);
p[i]={i,l,r};
}
sort(p+1,p+1+m);
for(int i=1,j=1;i<=m;i++){
int id=p[i].id,l=p[i].l,r=p[i].r;
while(j<=r){
if(last1[x[j]]){
if(last2[x[j]]) add(last2[x[j]],-1);
add(last1[x[j]],1);
last2[x[j]]=last1[x[j]];
}
last1[x[j]]=j;
j++;
}
ans[id]=sum(r)-sum(l-1);
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}