模板
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define size
using namespace std;
struct tree{
int l,r;
int mx,sum;
}t[size*4];
void build(int p,int l,int r)//建树 下标 左端点 右端点
{
t[p].l=l,t[p].r=r;
if(l==r)
{
t[p].mx=a[l],t[p].sum=a[l];
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void change(int p,int x,int v)//单点修改 当前下标 要修改的下标 目标值
{
if(t[p].l==t[p].r)
{
t[p].mx=v;return;
}
int mid=(t[p].l+t[p].r)/2;
if(x<=mid) change(p*2,x,v);//x属于左儿子
else change(p*2+1,x,v); //x属于右儿子
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
int ask(int p,int l,int r)//区间查询
{
if(l<=t[p].l&&r>=t[p].r) return t[p].mx;
int mid=(t[p].l+t[p].r)/2;
int val=-(1<<30);//负无穷大
if(l<=mid) val=max(val,ask(p*2,l,r));//左子节点重叠
if(r>mid) val=max(val,ask(p*2+1,l,r));//右子节点重叠
return val;
}
int main()
{
build(1,1,n);//调用入口
change(1,x,v);
cout<<ask(1,l,r)<<endl;
return 0;
}
带lazy标记的升级版
//by ziwan Catherine
//线段树
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100010
using namespace std;
//l,r表示cur节点对应的区间
//L,R,x表示要给区间[L,R]增加x
//sum[cur]表示节点cur的和
int lazy[N],sum[N];
void update(int cur){
sum[cur]=sum[cur<<1]+sum[cur<<1|1];
}
void pushdown(int cur,int t){//下传标记 当前节点 区间长度
lazy[cur<<1]+=lazy[cur];
lazy[cur<<1|1]+=lazy[cur];
sum[cur<<1]+=lazy[cur]*(t+1>>1);
sum[cur<<1|1]+=lazy[cur]*(t>>1);
lazy[cur]=0;
}
void add(int l,int r,int L,int R,int cur,int x){
if(L<=l&&R>=r){//被完全包含
lazy[cur]+=x;
sum[cur]+=(r-l+1)*x;
return;
}
pushdown(cur,l-r+1);
int mid=l+r>>1;
if(L<=mid) add(l,mid,L,R,cur<<1,x);//左儿子中有
if(R>mid) add(mid+1,r,L,R,cur<<1|1,x);//右儿子中有
update(cur);
}
int ask(int l,int r,int L,int R,int cur){
if(L<=l&&R>=r) return sum[cur];
pushdown(cur,r-l+1);
int mid=l+r>>1,ans=0;
if(L<=mid) ans+=ask(l,mid,L,R,cur<<1);
if(R>mid) ans+=ask(mid+1,r,L,R,cur<<1|1);
return ans;
}
int main(){
add(1,10,1,10,1,2);
printf("%d\n", ask(1,10,1,9,1));
}