题意:给n个数,m次查询,求[l,r]之间不重复数的个数。
思路:主席树。用一个map记录每个值在当前操作下最新的位置,从前往后插入主席树。对于查询[l,r],窝们在root[ l ]下查询在r之前的不重复数的个数。详见代码:
/*********************************************************
file name: spoj3267.cpp
author : kereo
create time: 2015年04月04日 星期六 14时29分56秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=30000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=1000000000+7;
#define L(x) (x->ch[0])
#define R(x) (x->ch[1])
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n,m,cnt,top;
int a[MAXN],st[MAXN*30];
struct node{
int num;
node *ch[2];
}nod[MAXN*30],*root[MAXN],nil,*null;
map<int,int>mp;
struct CMT{
void init(){
cnt=top=0;
nil.num=0; null=&nil;
L(null)=R(null)=null;
for(int i=0;i<=n+1;i++)
root[i]=null;
}
void newnode(node * &x,node *fa,int val){
if(top)
x=&nod[st[--top]];
else
x=&nod[cnt++];
if(fa == null){
x->num=val;
L(x)=R(x)=null;
}
else{
x->num=fa->num+val;
L(x)=L(fa); R(x)=R(fa);
}
}
void insert(node *&rt,node *fa,int l,int r,int pos,int val){
newnode(rt,fa,val);
if(l == r)
return ;
int mid=(l+r)>>1;
if(pos<=mid)
insert(L(rt),L(fa),l,mid,pos,val);
else
insert(R(rt),R(fa),mid+1,r,pos,val);
}
int query(node *rt,int pos){
int l=1,r=n,ans=0;
while(pos<r){
int mid=(l+r)>>1;
if(pos<=mid){
rt=L(rt);
r=mid;
}
else{
ans+=L(rt)->num;
rt=R(rt); l=mid+1;
}
}
return ans+rt->num;
}
}cmt;
int main(){
//freopen("in.txt","r",stdin);
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
cmt.init(); mp.clear();
for(int i=n;i>=1;i--){
if(mp.find(a[i]) == mp.end())
cmt.insert(root[i],root[i+1],1,n,i,1);
else{
cmt.insert(root[0],root[i+1],1,n,mp[a[i]],-1);
cmt.insert(root[i],root[0],1,n,i,1);
}
mp[a[i]]=i;
}
scanf("%d",&m);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",cmt.query(root[l],r));
}
}
return 0;
}