线段树模板——lazy数组优化找区间和,单点修改,区间修改,求区间的最大值最小值。
ll tree1[10000000];
ll tree2[10000000];
ll tree3[10000000];
ll lazy[10000000];
ll p;
ll a,b,c,d,e,f,g,h;
void Weihu(ll p)
{
tree1[p]=tree1[2*p]+tree1[2*p+1];
tree2[p]=max(tree2[2*p],tree2[2*p+1]);
tree3[p]=min(tree3[2*p],tree3[2*p+1]);
}
void down(ll p,ll left,ll right)
{
ll mid=(left+right)/2;
lazy[2*p]+=lazy[p];
lazy[2*p+1]+=lazy[p];
tree1[2*p]+=(mid-left+1)*(lazy[p]);
tree1[2*p+1]+=(right-mid)*lazy[p];
tree2[2*p]+=lazy[p];
tree2[2*p+1]+=lazy[p];
tree3[2*p]+=lazy[p];
tree3[2*p+1]+=lazy[p];
lazy[p]=0;
}
void Creat(ll p, ll left, ll right)
{
lazy[p]=0;
if(left==right)
{
scanf("%lld",&tree1[p]);
tree2[p]=tree3[p]=tree1[p];
return ;
}
ll mid=(left+right)/2;
Creat(2*p,left,mid);
Creat(2*p+1,mid+1,right);
Weihu(p);
}
void Modify(ll p, ll left, ll right, ll pos, ll num) //单点更新
{
if(left==right)
{
tree1[p]+=(right-left+1)*num;
tree2[p]=tree2[p]+num;
tree3[p]=tree3[p]+num;
lazy[p]+=num;
return ;
}
down(p,left,right);
ll mid=(left+right)/2;
if(pos<=mid)
Modify(2*p,left,mid,pos,num);
if(pos>mid)
Modify(2*p+1,mid+1,right,pos,num);
Weihu(p);
}
ll Add(ll p, ll left, ll right, ll l,ll r) //区间求和
{
if(l<=left&&r>=right)
return tree1[p];
down(p,left,right);
ll ans=0;
ll mid=(left+right)/2;
if(l<=mid)
ans=ans+Add(2*p,left,mid,l,r);
if(r>mid)
ans=ans+Add(2*p+1,mid+1,right,l,r);
return ans;
}
ll Find_max(ll p, ll left, ll right, ll l, ll r) //求最大值
{
if(l<=left&&r>=right)
return tree2[p];
down(p,left,right);
ll mid=(left+right)/2;
ll ans1=0;
if(l<=mid)
ans1=max(ans1,Find_max(2*p,left,mid,l,r));
if(r>mid)
ans1=max(ans1,Find_max(2*p+1,mid+1,right,l,r));
return ans1;
}
ll Find_min(ll p, ll left, ll right, ll l, ll r) // 求最小值
{
if(l<=left&&r>=right)
return tree3[p];
down(p,left,right);
ll mid=(left+right)/2;
ll ans1=0x3f3f3f3f;
if(l<=mid)
ans1=min(ans1,Find_min(2*p,left,mid,l,r));
if(r>mid)
ans1=min(ans1,Find_min(2*p+1,mid+1,right,l,r));
return ans1;
}
void Undata(ll p,ll left, ll right, ll l, ll r, ll num) //区间更新
{
if(left>=l&&right<=r)
{
tree1[p]+=(right-left+1)*num;
lazy[p]+=(num);
tree2[p]+=num;
tree3[p]+=num;
return ;
}
down(p,left,right);
ll mid=(left+right)/2;
if(l<=mid)
Undata(2*p,left,mid,l,r,num);
if(r>mid)
Undata(2*p+1,mid+1,right,l,r,num);
Weihu(p);
}