1 map<int,int>mp;//在线主席树 2 int a[N],tot,n,q; 3 int T[M],lson[M],rson[M],val[M]; 4 int bulid(int l,int r){ 5 int root=tot++; 6 val[root]=0; 7 int m=(l+r)>>1; 8 if(l!=r){ 9 lson[root]=bulid(l,m); 10 rson[root]=bulid(m+1,r); 11 } 12 return root; 13 } 14 int update(int root,int pos,int v){ 15 int newroot=tot++,tmp=newroot; 16 int l=1,r=n; 17 val[newroot]=val[root]+v; 18 while(l<r){ 19 int m=(l+r)>>1; 20 //更新的时候需要充分利用历史信息 21 //更新原来的左子树,右子树不变 22 if(pos<=m){ 23 lson[newroot]=tot++;rson[newroot]=rson[root]; 24 newroot=lson[newroot];root=lson[root]; 25 r=m; 26 } 27 //更新右子树 28 else{ 29 rson[newroot]=tot++;lson[newroot]=lson[root]; 30 newroot=rson[newroot];root=rson[root]; 31 l=m+1; 32 } 33 val[newroot]=val[root]+v; 34 } 35 return tmp; 36 } 37 int query(int root,int pos){ 38 int ret=0; 39 int l=1,r=n; 40 while(pos<r){ 41 int m=(l+r)>>1; 42 if(pos<=m){ 43 r=m; 44 root=lson[root]; 45 } 46 else{ 47 ret+=val[lson[root]]; 48 root=rson[root]; 49 l=m+1; 50 } 51 } 52 return ret+val[root]; 53 } 54 int main(){ 55 while(scanf("%d",&n)!=EOF){ 56 tot=0; //结点数 57 for(int i=1;i<=n;i++) 58 scanf("%d",&a[i]); 59 T[n+1]=bulid(1,n); 60 for(int i=n;i;i--){ 61 int nxt; 62 map<int,int>::iterator it=mp.find(a[i]); 63 if(it==mp.end()) nxt=n+1; 64 else nxt=it->second; 65 //如果这是第一次出现,也就是最后一个位置上,则直接更新 66 if(nxt>n) 67 T[i]=update(T[i+1],i,1); 68 //在原来的位置上擦掉,在当前位置更新 69 else{ 70 int t=update(T[i+1],nxt,-1); 71 T[i]=update(t,i,1); 72 } 73 mp[a[i]]=i; 74 } 75 scanf("%d",&q); 76 while(q--){ 77 int l,r; 78 scanf("%d%d",&l,&r); 79 printf("%d\n",query(T[l],r)); 80 } 81 } 82 return 0; 83 }
时间: 2024-10-12 16:32:09