线段树模板

///支持查询和区间的单值修改

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,a[N],m;
int sumv[N<<2];
void pushup(int o){sumv[o]=sumv[o<<1]+sumv[o<<1|1];}
void build(int o,int l,int r){
    if(l==r){sumv[o]=a[l];return;}
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    pushup(o);
}
void change(int o,int l,int r,int q,int v){
    if(l==r){sumv[o]+=v;return;}
    int mid=(l+r)>>1;
    if(q<=mid)change(o<<1,l,mid,q,v);
    else change(o<<1|1,mid+1,r,q,v);
    pushup(o); 
}
int querysum(int o,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr)return sumv[o];
    int ans=0;
    int mid=(l+r)>>1;
    if(ql<=mid)ans+=querysum(o<<1,l,mid,ql,qr);
    if(qr>mid)ans+=querysum(o<<1|1,mid+1,r,ql,qr);
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",a+i);
    build(1,1,n);
    while(m--){
        int opt;scanf("%d",&opt);
        if(opt==1){int x,y;scanf("%d%d",&x,&y);change(1,1,n,x,y);}
        if(opt==2){int l,r;scanf("%d%d",&l,&r);printf("%d
",querysum(1,1,n,l,r));}
    }
}
//求区间求最小值

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,a[N],m;
int minv[N<<2];
int pushup(int o){minv[o]=min(minv[o<<1],minv[o<<1|1]);}
void build(int o,int l,int r){
    if(l==r){minv[o]=a[l];return;}
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    pushup(o);
}
void change(int o,int l,int r,int q,int v){
    if(l==r){minv[o]+=v;return;}
    int mid=(l+r)>>1;
    if(q<=mid)change(o<<1,l,mid,q,v);
    else change(o<<1|1,mid+1,r,q,v);
    pushup(o); 
}
int querymin(int o,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr)return minv[o];
    int ans=1e9+7;
    int mid=(l+r)>>1;
    if(ql<=mid)ans=min(ans,querymin(o<<1,l,mid,ql,qr));
    if(qr>mid)ans=min(ans,querymin(o<<1|1,mid+1,r,ql,qr));
    return ans;
}
//对一段区间进行修改
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,a[N],m;
int sumv[N<<2],addv[N<<2];
int pushup(int o){sumv[o]=sumv[o<<1]+sumv[o<<1|1];}
void build(int o,int l,int r){
    addv[o]=0;
    if(l==r){sumv[o]=a[l];return;}
    int mid=(l+r)>>1;
    build(o<<1,l,mid);
    build(o<<1|1,mid+1,r);
    pushup(o);
}
inline void puttag(int o,int l,int r,int v){
    addv[o]+=v;sumv[o]+=(r-l+1)*v;
}
void pushdown(int o,int l,int r){
    if(addv[o]==0)return;
    addv[o<<1]+=addv[o];
    addv[o<<1|1]+=addv[o];
    int mid=(l+r)>>1;
    sumv[o<<1]+=addv[o]*(mid-l+1);
    sumv[o<<1|1]+=addv[o]*(r-mid);
    addv[o]=0;
}
void optadd(int o,int l,int r,int ql,int qr,int v){
    if(ql<=l&&r<=qr){puttag(o,l,r,v);return;}
    int mid=(l+r)>>1;
    pushdown(o,l,r);
    if(ql<=mid)optadd(o<<1,l,mid,ql,qr,v);
    if(qr>mid)optadd(o<<1|1,mid+1,r,ql,qr,v);
    pushup(o);
}
int querysum(int o,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr)return sumv[o];
    int ans=0;int mid=(l+r)>>1;
    pushdown(o,l,r);
    if(ql<=mid)ans+=querysum(o<<1,l,mid,ql,qr);
    if(qr>mid)ans+=querysum(o<<1|1,mid+1,r,ql,qr);
    return ans;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",a+i);
    build(1,1,n);
    while(m--){
        int opt;scanf("%d",&opt);
        if(opt==1){int l,r,v;scanf("%d%d%d",&l,&r,&v);optadd(1,1,n,l,r,v);}
        if(opt==2){int l,r;scanf("%d%d",&l,&r);printf("%d
",querysum(1,1,n,l,r));}
    }
}
原文地址:https://www.cnblogs.com/wjc2021/p/11237907.html