线段树模板
建树
struct node
{
int l,r,w,f;
}tree[400001];
void build(int l,int r,int k)
{
tree[k].l=l;tree[k].r=r;
if(l==r)
{
scanf("%d",&tree[k].w);
return ;
}
int m=(l+r)/2;
build(l,m,k*2);
build(m+1,r,k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
单点查询(即查询一个点的状态,设待查询点为x)
void ask(int k)
{
if(tree[k].l==tree[k].r)
{
ans=tree[k].w;
return ;
}
int m=(tree[k].l+tree[k].r)/2;
if(x<=m) ask(k*2);
else ask(k*2+1);
}
单点修改(即更改某一个点的状态,对第x个数加上y)
void add(int k)
{
if(tree[k].l==tree[k].r)
{
tree[k].w+=y;
return;
}
int m=(tree[k].l+tree[k].r)/2;
if(x<=m) add(k*2);
else add(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
区间查询(即查询一段区间的状态)//不带lazy tag
void sum(int k)
{
if(tree[k].l>=x&&tree[k].r<=y)
{
ans+=tree[k].w;
return;
}
int m=(tree[k].l+tree[k].r)/2;
if(x<=m) sum(k*2);
if(y>m) sum(k*2+1);
}
区间修改(即修改一段连续区间的值,给区间[a,b]的每个数都加x)
标记下传
void down(int k)
{
tree[k*2].f+=tree[k].f;
tree[k*2+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f=0;
}
inline void change_interval(int k)
{
if(tree[k].l>=a&&tree[k].r<=b)
{
tree[k].w+=(tree[k].r-tree[k].l+1)*y;
tree[k].f+=y;
return;
}
if(tree[k].f) down(k);
int m=(tree[k].l+tree[k].r)/2;
if(a<=m) change_interval(k*2);
if(b>m) change_interval(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
区间查询(即查询一段区间的状态)//带lazy tag
inline void ask_interval(int k)
{
if(tree[k].l>=a&&tree[k].r<=b)
{
ans+=tree[k].w;
return;
}
if(tree[k].f) down(k);
int m=(tree[k].l+tree[k].r)/2;
if(a<=m) ask_interval(k*2);
if(b>m) ask_interval(k*2+1);
}