线段树模板
单点更新+区间查询
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ll long long
#define l(p) t[p].l //区间左端点
#define r(p) t[p].r //区间右端点
#define mid (l(p)+r(p))/2
#define sum(p) t[p].sum
#define lp p<<1 //左孩子
#define rp (p<<1)|1 //右孩子
using namespace std;
const int maxN = 2e5+10;
int a[maxN];
struct Node{
int l,r,sum;
}t[maxN*4];
void build(int p,int l, int r){
l(p)=l;r(p)=r;
if(l==r){
sum(p)=a[l];
return;
}
build(lp, l, mid);
build(rp,mid+1,r);
sum(p)=sum(lp)+sum(rp);
}
void change(int p,int x,int v){
if(l(p)==r(p)){ //直到找到叶节点
sum(p)=v;
return;
}
if(x<=mid) change(lp, x, v);
else change(rp, x, v);
sum(p)=sum(lp)+sum(rp); //这一步不要忘记更新信息
}
int ask(int p,int l,int r){
if(l<=l(p)&&r>=r(p)) return sum(p);
int res=0;
if(l<=mid) res+=sum(lp);
if(r>mid) res+=sum(rp);
return res;
}
int n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1, 1, n); //不要忘记建树
while(m--){
char s[10];int l,r,x,v;
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d",&x,&v);
change(1, x, v);
}else{
scanf("%d%d",&l,&r);
printf("%d\n",ask(1, l, r));
}
}
}
区间修改(lazy tag)
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#define ll long long
#define l(p) t[p].l //区间左端点
#define r(p) t[p].r //区间右端点
#define mid (l(p)+r(p))/2
#define sum(p) t[p].sum
#define lp p<<1 //左孩子
#define rp (p<<1)|1 //右孩子
#define tag(p) t[p].tag
using namespace std;
const int maxN = 2e5+10;
int a[maxN];
struct Node{
int l,r,sum;
int tag=1;
}t[maxN*4];
void build(int p,int l, int r){
l(p)=l;r(p)=r;
if(l==r){
sum(p)=a[l];
return;
}
build(lp, l, mid);
build(rp,mid+1,r);
sum(p)=sum(lp)+sum(rp);
}
void putdown(int p){
if(tag(p)!=1){
//更新左右节点
sum(lp)*=tag(p);
sum(rp)*=tag(p);
//左右节点打上延迟标记
tag(lp)=2*tag(p);
tag(rp)=2*tag(p);
tag(p)=1; //父节点标记删除
}
}
void change(int p,int l,int r){
if(l<=l(p)&& r>=r(p)){
sum(p)*=2;
tag(p)*=2;
return;
}
putdown(p); //最好写
if(l<=mid) change(lp, l, r);
if(r>mid) change(rp,l,r);
sum(p)=sum(lp)+sum(rp); //这一步不要忘记更新信息
}
int ask(int p,int l,int r){
if(l<=l(p)&&r>=r(p)) return sum(p);
putdown(p); //自上而下的访问信息,这里必须下穿标记
int res=0;
if(l<=mid) res+=ask(lp, l, r);
if(r>mid) res+=ask(rp, l, r);
return res;
}
int n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1, 1, n); //不要忘记建树
while(m--){
char s[10];int l,r;
scanf("%s%d%d",s,&l,&r);
if(s[0]=='C'){
change(1,l,r);
}else{
printf("%d\n",ask(1, l, r));
}
}
}
来源:CSDN
作者:牛顿和我是好朋友
链接:https://blog.csdn.net/qq_44846324/article/details/104175262