线段树动态开点
Posted cutemush
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树动态开点相关的知识,希望对你有一定的参考价值。
//zz https://blog.csdn.net/u012972031/article/details/88751811
//https://www.luogu.org/problemnew/show/P3372
#include<cstdio> #include<iostream> using namespace std; const int N=300010; struct node{ int ls,rs,lazy; long long sum; }tr[N]; int root=0,cnt=0; void insert(int &root,int l,int r,int ll,int rr,int x) { if(!root) root=++cnt; int b=min(r,rr)-max(l,ll)+1; tr[root].sum+=b*x; if(l>=ll&&r<=rr) { tr[root].lazy+=x; return; } int mid=l+r>>1; if(ll<=mid) insert(tr[root].ls,l,mid,ll,rr,x); if(rr>mid) insert(tr[root].rs,mid+1,r,ll,rr,x); } long long query(int root,int l,int r,int ll,int rr) { if(l>=ll&&r<=rr) return tr[root].sum; int mid=l+r>>1; if(tr[root].lazy) { if(!tr[root].ls) tr[root].ls=++cnt; tr[tr[root].ls].lazy+=tr[root].lazy; tr[tr[root].ls].sum+=tr[root].lazy*(mid-l+1); if(!tr[root].rs) tr[root].rs=++cnt; tr[tr[root].rs].lazy+=tr[root].lazy; tr[tr[root].rs].sum+=tr[root].lazy*(r-mid); tr[root].lazy=0; } long long ans=0; if(ll<=mid) ans+=query(tr[root].ls,l,mid,ll,rr); if(rr>mid) ans+=query(tr[root].rs,mid+1,r,ll,rr); return ans; } int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) { int temp; cin>>temp; insert(root,1,n,i,i,temp); } for(int i=1;i<=m;i++) { int ta,tb,tc,td; cin>>ta>>tb>>tc; if(ta==1) { cin>>td; insert(root,1,n,tb,tc,td); } else if(ta==2) { cout<<query(root,1,n,tb,tc)<<endl; } } return 0; }
以上是关于线段树动态开点的主要内容,如果未能解决你的问题,请参考以下文章