线段树模板

线段树模板——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);
} 

你可能感兴趣的:(线段树)