[COGS2554][SYZOJ247][福利]可持久化线段树

思路:

主席树模板。

注意内存的分配,原始的线段树有$2n$个结点,每次更新时最多增加$log(n)$个结点,总共有$q$次询问,所以存储结点的数组大小为$2N+q log(n)$。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<vector>
 4 #include<algorithm>
 5 inline int getint() {
 6     char ch;
 7     while(!isdigit(ch=getchar()));
 8     int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int N=10001,Q=100001,logN=100;
13 class FotileTree {
14     private:
15         unsigned int left[(N<<1)+Q*logN],right[(N<<1)+Q*logN];
16         std::vector<int> val;
17         void push_up(const int p) {
18             val[p]=std::max(val[left[p]],val[right[p]]);
19         }
20     public:
21         unsigned int root[Q];
22         unsigned int newnode() {
23             val.push_back(0);
24             return val.size()-1;
25         }
26         void build(const int p,const int b,const int e) {
27             if(b==e) {
28                 val[p]=getint();
29                 return;
30             }
31             int mid=(b+e)>>1;
32             build(left[p]=newnode(),b,mid);
33             build(right[p]=newnode(),mid+1,e);
34             push_up(p);
35         }
36         unsigned int modify(const int p,const int b,const int e,const int x,const int y) {
37             unsigned int new_p=newnode();
38             if(b==e) {
39                 val[new_p]=y;
40                 return new_p;
41             }
42             int mid=(b+e)>>1;
43             if(x<=mid) left[new_p]=modify(left[p],b,mid,x,y),right[new_p]=right[p];
44             if(x>mid) right[new_p]=modify(right[p],mid+1,e,x,y),left[new_p]=left[p];
45             push_up(new_p);
46             return new_p;
47         }
48         int query(const int p,const int b,const int e,const int l,const int r) {
49             if((b==l)&&(e==r)) return val[p];
50             int mid=(b+e)>>1;
51             int ans=0;
52             if(l<=mid) ans=std::max(ans,query(left[p],b,mid,l,std::min(mid,r)));
53             if(r>mid) ans=std::max(ans,query(right[p],mid+1,e,std::max(mid+1,l),r));
54             return ans;
55         }
56 };
57 FotileTree t;
58 int main() {
59     freopen("longterm_segtree.in","r+",stdin);
60     freopen("longterm_segtree.out","w+",stdout);
61     int n=getint(),q=getint(),ver=0;
62     t.build(t.root[++ver]=t.newnode(),1,n);
63     while(q--) {
64         int op=getint(),k=getint(),x=getint(),y=getint();
65         if(!op) printf("%d\n",t.query(t.root[k],1,n,x,y));
66         if(op) t.root[++ver]=t.modify(t.root[k],1,n,x,y);
67     }
68     fclose(stdin),fclose(stdout);
69     return 0;
70 } 

 

posted @ 2017-07-14 10:55  skylee03  阅读(133)  评论(0编辑  收藏  举报