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

主席树(可持久化线段树版)

时间:2017-08-06 19:25:26      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:区间   线段树   ==   pre   初始化   add   大小   style   init   

求区间和模板

 1 struct node{
 2     int l[maxn*20],r[maxn*20];  //区间大小    maxn = 1e5时为20倍,不够就开40
 3     int li[maxn*20],ri[maxn*20];//左孩子和右孩子的位置
 4     int sum[maxn*20],add[maxn*20]; //区间和,懒惰标记
 5     int tot;///数组大小,使用的时候先初始化为0
 6 
 7     void init(int x,int y){
 8         li[x] = li[y];  l[x] = l[y];
 9         ri[x] = ri[y];  r[x] = r[y];
10         sum[x] = sum[y]; add[x] = add[y];
11     }
12 
13     void build(int &pos,int L,int R){//建树,也可以建一个空树
14         pos = ++tot;
15         sum[pos] = 0;
16         l[pos] = L;
17         r[pos] = R;
18         add[pos] = 0;
19         if(L == R){
20             scanf("%intd",&sum[pos]);
21             return;
22         }
23         int mid = (L+R)>>1;
24         build(li[pos],L,mid);
25         build(ri[pos],mid+1,R);
26         sum[pos] = sum[li[pos]] + sum[ri[pos]];
27     }
28 
29     void update(int L,int R,int &x,int y,int k){//区间修改,x传入低k棵线段树的根节点,y为第k-1棵线段树的根节点
30         x = ++tot;
31         init(x,y);
32         if(L == l[x] && R == r[x]){
33             sum[x] += (R-L+1)*k;
34             add[x] += k;
35             return;
36         }
37         sum[x] += (R - L + 1)*k;
38         int mid = (l[x]+r[x])>>1;
39         if(R <= mid){
40             update(L,R,li[x],li[y],k);
41         }
42         else if(L > mid){
43             update(L,R,ri[x],ri[y],k);
44         }
45         else{
46             update(L,mid,li[x],li[y],k);
47             update(mid+1,R,ri[x],ri[y],k);
48         }
49     }
50 
51     int query(int L,int R,int pos,int add1){//查询第根节点为pos的树的l,r和,add1为父亲节点的add累加和,初始传入0
52         if(L == l[pos] && R == r[pos]){
53             return sum[pos] + add1*(R-L+1);
54         }
55         int mid = (l[pos]+r[pos])/2;
56         if(R <= mid){
57             return query(L,R,li[pos],add[pos]+add1);
58         }
59         else if(L > mid){
60             return query(L,R,ri[pos],add[pos]+add1);
61         }
62         else{
63             return query(L,mid,li[pos],add[pos]+add1)+query(mid+1,R,ri[pos],add[pos]+add1);
64         }
65     }
66 }tre;

 

主席树(可持久化线段树版)

标签:区间   线段树   ==   pre   初始化   add   大小   style   init   

原文地址:http://www.cnblogs.com/yZiii/p/7295459.html

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