线段树模板
Posted zenghuan0620
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树模板相关的知识,希望对你有一定的参考价值。
区间修改:
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; int sum[N<<2],lazy[N<<2],a[N]; void pushup(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void pushdown(int l,int r,int rt) { if(lazy[rt]==0)return; lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; int mid=(l+r)>>1; sum[rt<<1]+=(mid-l+1)*lazy[rt]; sum[rt<<1|1]+=(r-mid)*lazy[rt]; lazy[rt]=0; } void build(int l,int r,int rt) { lazy[rt]=0; if(l==r) { sum[rt]=a[l]; return; } int mid=(l+r)>>1; pushdown(l,r,rt); build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } void update(int L,int R,int val,int l,int r,int rt) { if(L<=l&&r<=R) { lazy[rt]+=val; sum[rt]+=(r-l+1)*val; return; } int mid=(l+r)>>1; pushdown(l,r,rt); if(L<=mid)update(L,R,val,l,mid,rt<<1); if(R>mid)update(L,R,val,mid+1,r,rt<<1|1); pushup(rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R)return sum[rt]; int mid=(l+r)>>1,ans=0; pushdown(l,r,rt); if(L<=mid)ans=ans+query(L,R,l,mid,rt<<1); if(R>mid)ans=ans+query(L,R,mid+1,r,rt<<1|1); pushup(rt); return ans; } int main() { int n=5; a[1]=5,a[2]=2,a[3]=1,a[4]=7,a[5]=4; build(1,n,1); update(1,4,5,1,n,1); printf("%d",query(3,5,1,n,1)); return 0; }
单点修改
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; int sum[N<<2],a[N]; void pushup(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; // =max() // =min() // =gcd() // =lcm() } void build(int l,int r,int rt) { if(l==r) { sum[rt]=a[l]; return; } int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } void update(int pos,int val,int l,int r,int rt) { if(pos<=l&&r<=pos) { sum[rt]=val; return; } int mid=(l+r)>>1; if(pos<=mid)update(pos,val,l,mid,rt<<1); else update(pos,val,mid+1,r,rt<<1|1); pushup(rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R)return sum[rt]; int mid=(l+r)>>1,ans=0; if(L<=mid)ans=ans+query(L,R,l,mid,rt<<1); if(R>mid)ans=ans+query(L,R,mid+1,r,rt<<1|1); pushup(rt); return ans; } int main() { int n=5; a[1]=5,a[2]=2,a[3]=1,a[4]=7,a[5]=4; build(1,n,1); update(3,8,1,n,1); printf("%d",query(3,5,1,n,1)); return 0; }
模板题:
https://www.luogu.org/problem/P3372
https://www.luogu.org/problem/P3373
以上是关于线段树模板的主要内容,如果未能解决你的问题,请参考以下文章