线段树是一种可以根据子问题解决父问题的数据结构
比如说
求一段区间的和(\(\sum_{i=L}^Ra_i=\sum_{i=L}^Ma_i+\sum_{i=M+1}^Ra_i\quad ,L\leq M<R\))
求一段区间的最大值(\(\max_{i=L}^Ra_i=\max(\max_{i=L}^Ma_i,\max_{i=M+1}^Ra_i)\quad ,L\leq M<R\))
可以用线段树维护的问题必须满足 区间加法 ,否则是不可能将大问题划分成子问题来解决的。
例题:
P3372 【模板】线段树 1 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
板子:
struct point{
int l,r;
i64 sum,add;
}tr[N*4];
void pushup(int u){
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void pushdown(int u){
auto &root=tr[u];
auto &left=tr[u<<1];
auto &right=tr[u<<1|1];
if(root.add){
left.add+=root.add;left.sum+=(i64)(left.r-left.l+1)*root.add;
right.add+=root.add;right.sum+=(i64)(right.r-right.l+1)*root.add;
root.add=0;
}
}
void build(int u,int l,int r){
if(l==r){
tr[u]={l,r,a[l],0};
}
else{
tr[u]={l,r};
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
}
void modify(int u,int l,int r,int d){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].sum+=(i64)(tr[u].r-tr[u].l+1)*d;
tr[u].add+=d;
}
else{
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)modify(u<<1,l,r,d);
if(r>mid)modify(u<<1|1,l,r,d);
pushup(u);
}
}
i64 query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r)return tr[u].sum;
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
i64 sum=0;
if(l<=mid)sum=query(u<<1,l,r);
if(r>mid)sum+=query(u<<1|1,l,r);
return sum;
}
标签:int,max,线段,tr,Ra,sum From: https://www.cnblogs.com/liangqianxing/p/17062662.html先鸽了以后再补充