在线主席树不同数

 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 }

 

posted @ 2015-04-08 00:04  AI_Believer  阅读(134)  评论(0编辑  收藏  举报