一、基础操作:区间求和lazy标记
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010;
int in[maxn+2];//数据初值
struct tree{
int l,r;
ll lazy,sumn;
}a[4*maxn+9];
void build(int p,int l,int r){
a[p].l=l,a[p].r=r;
if(l==r){
a[p].sumn=in[l];
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
a[p].sumn=a[p<<1].sumn+a[p<<1|1].sumn;
}
void push_down(int p){//下传懒惰标记
a[p<<1].sumn+=a[p].lazy*(a[p<<1].r-a[p<<1].l+1);
a[p<<1|1].sumn+=a[p].lazy*(a[p<<1|1].r-a[p<<1|1].l+1);
a[p<<1].lazy+=a[p].lazy;
a[p<<1|1].lazy+=a[p].lazy;
a[p].lazy=0;
}
void change(int p,int l,int r,int k){
if(l<=a[p].l&&r>=a[p].r){//找到完全覆盖的区间
a[p].sumn+=k*(a[p].r-a[p].l+1);
a[p].lazy+=k;
return;
}
push_down(p);//下传标记
int mid=a[p].l+a[p].r>>1;
if(l<=mid) change(p<<1,l,r,k);//和左儿子有交集
if(r>mid) change(p<<1|1,l,r,k);
a[p].sumn=a[p<<1].sumn+a[p<<1|1].sumn;//维护父子逻辑
}
ll ask(int p,int l,int r){//区间询问求和
if(l<=a[p].l&&r>=a[p].r) return a[p].sumn;
push_down(p);//每次都要下传标记
int mid=(a[p].l+a[p].r)>>1;
ll ans=0;
if(l<=mid) ans+=ask(p<<1,l,r);
if(r>mid) ans+=ask(p<<1|1,l,r);
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
int n,m,x,b,c,e;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>in[i];
build(1,1,n);
for(int i=1;i<=m;i++){
cin>>x;
if(x==1){
cin>>b>>c>>e;
change(1,b,c,e);
}
else{
cin>>b>>c;
cout<<ask(1,b,c)<<endl;
}
}
return 0;
}
二、区间最大值
#include <bits/stdc++.h>
using namespace std;
const int maxn=200009;
int n,m,in[maxn];
struct node{
int v,l,r,lazy;
}a[maxn*4];
void build(int p,int l,int r){
a[p].l=l,a[p].r=r;
if(l==r){
a[p].v=in[l];
return;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
a[p].v=max(a[p<<1].v,a[p<<1|1].v);
}
void change(int p,int l,int r,int k){
if(a[p].l==l&&a[p].r==r){//到达叶子节点
if(a[p].v<k)//开始修改
a[p].v=k;
return;
}
int mid=a[p].l+a[p].r>>1;
if(l<=mid) change(p<<1,l,r,k);//找节点
else change(p<<1|1,l,r,k);
a[p].v=max(a[p<<1].v,a[p<<1|1].v);
}
int Max=0;
void ask(int p,int l,int r){
if(a[p].l>=l&&a[p].r<=r){
Max=max(Max,a[p].v);
return;
}
int ans=0;
int mid=a[p].l+a[p].r>>1;
if(l<=mid) ask(p<<1,l,r);
if(r>mid) ask(p<<1|1,l,r);
return;
}
int main()
{
string s;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>in[i];
int b,c;
build(1,1,n);
for(int i=1;i<=m;i++)
{
cin>>s;
if(s[0]=='U'){
cin>>b>>c;
change(1,b,b,c);
}
else{
Max=0;
cin>>b>>c;
ask(1,b,c);
cout<<Max<<endl;
}
}
return 0;
}