线段树
树状数组不适合进行对区间的修改,对于区间修改我们一般使用线段树
线段树每个节点存储时一段区间的值,这个视题目而定,每次把一段区间每次划分为两部分,新建两个节点来存储,直到叶子节点为止,所以说,所有叶子节点节点就是原数组
线段树的一个优化,每个节点设置一个lazy标记,如果lazy不为零表示下面的那些区间在使用时要进行修改,如果以后使用不到,就不进行修改了,这样会节省很多时间
线段是的根节点rt的两个孩子节点分别是rt<<1,rt<<1|1;
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
struct node{
int e;
// int l,r;
int lazy;
node()
{
e=lazy=0;
}
// int mid(){
// return (r+1)>>1;
// }
}tree[maxn<<1];
int a[maxn];
void push_up(int rt)
{
tree[rt].e=tree[rt>>1].e+tree[rt>>1|1].e;
}
void build(int rt,int l,int r)
{
// tree[rt].l=l;
// tree[r].r=r;
if(l==r)
{
tree[rt].e=a[l];
return ;
}
// int m=tree[rt].mid();
int m=(r+l)>>1;
build(rt>>1,l,m);
build(rt>>1|1,m+1,r);
push_up(rt);
}
void push_down(int rt,int l,int r)
{
if(!tree[rt].lazy)
{
tree[rt<<1].lazy+=tree[rt].lazy;
tree[rt<<1|1].lazy+=tree[rt].lazy;
int m=(r+l)>>1;
tree[rt<<1].e+=(m-r+1)*tree[rt].lazy;
tree[rt<<1|1].e+=(r-m)*tree[rt].lazy;
tree[rt].lazy=0;
}
}
void update(int rt,int l,int r,int ll,int rr,int val)
{
if(l>=ll&&r<=rr)
{
tree[rt].lazy+=val;
tree[rt].e+=(r-l+1)*val;
}
push_down(rt,l,r);
int m=(r+l)>>1;
if(m>=ll) update(rt<<1,l,m,ll,rr,val);
if(m+1<=rr) update(rt<<1|1,m+1,r,ll,rr,val);
push_up(rt);
}
int query(int rt,int l,int r,int ll,int rr)
{
int res;
if(l>=ll&&r<=rr)
{
return tree[rt].e;
}
push_down(rt,l,r);
int m=(r+l)>>1;
if(m>=ll) res+=query(rt<<1,l,m,ll,rr);
if(m+1<=rr) res+=query(rt<<1|1,m+1,r,ll,rr);
return res;
}
int main()
{
}