首页 > 代码库 > 主席树(可持久化线段树版)
主席树(可持久化线段树版)
求区间和模板
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;
主席树(可持久化线段树版)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。