码迷,mamicode.com
首页 > 其他好文 > 详细

在线主席树不同数

时间:2015-04-08 00:56:45      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

 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 }

 

在线主席树不同数

标签:

原文地址:http://www.cnblogs.com/chxer/p/4401112.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!