130 线段树
作者:互联网
视频链接:
// P3374 【模板】树状数组 1 #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define lc p<<1 #define rc p<<1|1 #define N 500005 int n,w[N]; struct node{ int l,r,sum; }tr[N*4]; void pushup(int p){//向上更新 tr[p].sum=tr[lc].sum+tr[rc].sum; } void build(int p,int l,int r){//建树 tr[p]={l,r,w[l]}; if(l==r) return; //是叶子则返回 int m=l+r>>1; //不是叶子则裂开 build(lc,l,m); build(rc,m+1,r); pushup(p); } void update(int p,int x,int k){//点修改 if(tr[p].l==x&&tr[p].r==x){//叶子则修改 tr[p].sum+=k; return; } int m=tr[p].l+tr[p].r>>1;//非叶子则裂开 if(x<=m) update(lc,x,k); if(x>m) update(rc,x,k); pushup(p); } int query(int p,int x,int y){//区间查询 if(x<=tr[p].l&&tr[p].r<=y)//覆盖则返回 return tr[p].sum; int m=tr[p].l+tr[p].r>>1;//不覆盖则裂开 int sum=0; if(x<=m) sum+=query(lc,x,y); if(y>m) sum+=query(rc,x,y); return sum; } int main(){ ios::sync_with_stdio(0); int m,op,x,y; cin>>n>>m; for(int i=1;i<=n;i++) cin>>w[i]; build(1,1,n); while(m--){ cin>>op>>x>>y; if(op==1) update(1,x,y); else cout<<query(1,x,y)<<endl; } return 0; } //Luogu P3372 【模板】线段树 1 #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define lc p<<1 #define rc p<<1|1 #define N 100005 #define LL long long LL n,w[N]; struct node{ LL l,r,sum,add; }tr[N*4]; void pushup(LL p){ tr[p].sum=tr[lc].sum+tr[rc].sum; } void pushdown(LL p){ auto &u=tr[p],&l=tr[lc],&r=tr[rc]; if(u.add){ l.sum+=u.add*(l.r-l.l+1), r.sum+=u.add*(r.r-r.l+1), l.add+=u.add, r.add+=u.add, u.add=0; } } void build(LL p,LL l,LL r){ tr[p]={l,r,w[l],0}; if(l==r) return; //是叶子则返回 LL m=l+r>>1; //不是叶子则裂开 build(lc,l,m); build(rc,m+1,r); pushup(p); } void update(LL p,LL x,LL y,LL k){ if(x<=tr[p].l&&tr[p].r<=y){//覆盖则修改 tr[p].sum+=(tr[p].r-tr[p].l+1)*k; tr[p].add+=k; return; } LL m=tr[p].l+tr[p].r>>1; //不覆盖则裂开 pushdown(p); if(x<=m) update(lc,x,y,k); if(y>m) update(rc,x,y,k); pushup(p); } LL query(LL p,LL x,LL y){ if(x<=tr[p].l&&tr[p].r<=y)//覆盖则返回 return tr[p].sum; LL m=tr[p].l+tr[p].r>>1;//不覆盖则裂开 pushdown(p); LL sum=0; if(x<=m) sum+=query(lc,x,y); if(y>m) sum+=query(rc,x,y); return sum; } int main(){ LL m,op,x,y,k; cin>>n>>m; for(LL i=1; i<=n; i ++) cin>>w[i]; build(1,1,n); while(m--){ cin>>op>>x>>y; if(op==2)cout<<query(1,x,y)<<endl; else cin>>k,update(1,x,y,k); } return 0; }
标签:int,线段,update,sum,130,build,rc,LL 来源: https://www.cnblogs.com/dx123/p/16319838.html