#include<iostream>
#include<cstdio>
#define N 50005
#define mid ((l + r )>>1)
using namespace std;
int num[N];//数据数组,用于存放数据
int tree[N<<2];//线段树数组,用于构造线段树
int lazy[N<<2];//懒惰标记,用于区间更新
//向上更新,t为节点下标
void PushUp(int t)
{
tree[t]=tree[t<<1]+tree[t<<1|1];
return ;
}
//向下更新,r为根节点,lr为r的管理区间左右边界
void PushDown(int l,int r,int t)
{
if(lazy[t])
{//如果有lazy值则下推
//lazy值下推给左右节点
lazy[t<<1]+=lazy[t];
lazy[t<<1|1]+=lazy[t];
//左右节点的值也要改变
//改变为 lazy值*管理节点个数
tree[t<<1]+=lazy[t]*(mid-r+1);
tree[t<<1|1]+=lazy[t]*(l-mid);
lazy[t]=0;
}
}
//建树,lr为建树左右区间边界,t为根节点
void Build(int l,int r,int t)
{
if(l==r)
{//找到叶子节点
tree[t]=num[l];//赋值
return ;
}
Build(l,mid,t<<1);//建左子树
Build(mid+1,r,t<<1|1);//建右子树
PushUp(t);//更新数据
return ;
}
//单点更新,p为更新位置,v为更新值,lr为根节点管理左右区间,t为根节点
void UpdatePoint(int p,int v,int l,int r,int t)
{
if(l==r&& l == p)
{//找到叶子节点
tree[t]+=v;
return ;
}
if(p<=mid)//目标点在左子区间
UpdatePoint(p,v,l,mid,t<<1);
else //目标点在左子区间
UpdatePoint(p,v,mid+1,r,t<<1|1);
PushUp(t);//更新数据
return ;
}
//区间更新,LR为更新区间左右边界,v为要加上的值,lr为根节点管理区间左右边界,t为根节点
void UpdateRange(int L,int R,int v,int l,int r,int t)
{
if(L<=l&&R>=r)
{//如果找到一个能全部被包含于修改范围的区间
lazy[t]+=v;//则加上懒惰标记
tree[t]+=v*(r-l+1);//同时也要修改区间和,与pushdown的修改同理
return ;
}
PushDown(l,r,t);//修改时也要将之前的懒惰标记下移
//递归寻找能全被包含的区间
if(L<=mid)UpdateRange(L,R,v,l,mid,t<<1);
if(R>mid) UpdateRange(L,R,v,mid+1,r,t<<1|1);
PushUp(t);
}
//区间查询,LR为查询区间左右边界,lr为根节点管理区间左右边界,t为根节点
int Query(int L,int R,int l,int r,int t)
{
if(L<=l&&R>=r)
{//找到目标区间
return tree[t];
}
PushDown(l,r,t);//如果有lazy值要下推
if(R<=mid)
return Query(L,R,l,mid,t<<1);
else if(L>mid)
return Query(L,R,mid+1,r,t<<1|1);
else return Query(L,R,l,mid,t<<1)+Query(L,R,mid+1,r,t<<1|1);
}
int main()
{
int t,n,a,b,k=1,v;
string s;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>num[i];
Build(1,n,1);
printf("Case %d:\n",k++);
while(cin>>s&&s!="End")
{
cin>>a>>b;
if(s=="Query")
cout<<Query(a,b,1,n,1)<<endl;
else if(s=="Add")
UpdatePoint(a,b,1,n,1);
else if(s=="Sub")
UpdatePoint(a,-b,1,n,1);
else if(s=="Range")
{cin>>v;UpdateRange(a,b,v,1,n,1);}
}
}
return 0;
}
线段树模板代码+详细注释
最新推荐文章于 2022-09-03 11:50:23 发布