[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 } 

 

转载于:https://www.cnblogs.com/skylee03/p/7168958.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值