JuQueen(线段树 lazy)

JuQueen

Time Limit: 5 Sec  Memory Limit: 512 MB

Description

 

Input

 

Output

 

Sample Input

10 10 5
state 0
groupchange 2 9 7
state 9
groupchange 0 2 10
change 0 -5

Sample Output

0
7
7
3
-3


线段树lazy的巧用
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define LL long long

using namespace std;

const int Num = 5000000;

typedef struct Tree
{
    int Min;//所表示区间的最大值
    
    int Max;//所表示区间的最小值
    
    int lazy;//区间所要变化的值
} Tree;

Tree Tr[Num*5];

char str[15];

int c,n,o;

void Pushup(int st)
{
    Tr[st].Max = max(Tr[st<<1].Max,Tr[st<<1|1].Max);

    Tr[st].Min = min(Tr[st<<1].Min,Tr[st<<1|1].Min);

    Tr[st].Min += Tr[st].lazy;

    Tr[st].Max += Tr[st].lazy;
}

void Build(int L,int R,int st)
{
    Tr[st].Max=0;
   
    Tr[st].Min=0;
   
    Tr[st].lazy=0;
    
    if(L==R)
    {
        return ;
    }
    int mid =(L+R)>>1;
    
    Build(L,mid,st<<1);
    
    Build(mid+1,R,st<<1|1);
    
    Pushup(st);
}

void Update(int L,int R,int st,int l,int r,int s)
{
    if(L>r||R<l)
    {
        return ;
    }
    
    if(L>=l&&R<=r)//区间更新
    {
        Tr[st].lazy+=s;
        
        Tr[st].Max+=s;
        
        Tr[st].Min+=s;
        
        return ;
    }
    int mid = (L+R)>>1;
    
    Update(L,mid,st<<1,l,r,s);
    
    Update(mid+1,R,st<<1|1,l,r,s);
    
    Pushup(st);
}

Tree Query(int L,int R,int st,int l,int r,int s)
{
    Tree p,q;
    
    p.Max=0;
    
    p.Min=c;
    
    if(L>r||R<l)
    {
        return p;
    }
    
    if(L>=l&&R<=r)
    {
        p.Max=Tr[st].Max+s;
    
        p.Min=Tr[st].Min+s;
    
        return p;
    }
    int mid = (L+R)>>1;
    
    s+=Tr[st].lazy;
    //将lazy所表示的逐层向下更新
    if(l<=mid)
    {
        q=Query(L,mid,st<<1,l,r,s);
    
        p.Max=max(q.Max,p.Max);
    
        p.Min=min(q.Min,p.Min);
    }
    if(r>mid)
    {
        q=Query(mid+1,R,st<<1|1,l,r,s);
    
        p.Max=max(q.Max,p.Max);
    
        p.Min=min(q.Min,p.Min);
    }
    return p;
}

int main()
{
    int l,r,s;
    
    Tree p;
    
    while(~scanf("%d %d %d",&n,&c,&o))
    {
        Build(1,n,1);
    
        for(int i=0; i<o; i++)
        {
            scanf("%s",str);
    
            if(!strcmp(str,"change"))
            {
                scanf("%d %d",&l,&s);
    
                r=++l;
    
                p=Query(1,n,1,l,r,0);
    
                if(s<0)
                {
                    if(p.Min+s>=0)
                    {
                        printf("%d
",s);
    
                        Update(1,n,1,l,r,s);
                    }
                    else
                    {
                        printf("%d
",-p.Min);
    
                        Update(1,n,1,l,r,-p.Min);
                    }
                }
                else
                {
                    if(p.Max+s<=c)
                    {
                        printf("%d
",s);
    
                        Update(1,n,1,l,r,s);
                    }
                    else
                    {
                        printf("%d
",c-p.Max);
    
                        Update(1,n,1,l,r,c-p.Max);
                    }
                }

            }
            else if(!strcmp(str,"groupchange"))
            {
                scanf("%d %d %d",&l,&r,&s);
    
                l++,r++;
    
                p=Query(1,n,1,l,r,0);
    
                if(s<0)
                {
                    if(p.Min+s>=0)
                    {
                        printf("%d
",s);
    
                        Update(1,n,1,l,r,s);
                    }
                    else
                    {
                        printf("%d
",-p.Min);
    
                        Update(1,n,1,l,r,-p.Min);
                    }
                }
                else
                {
                    if(p.Max+s<=c)
                    {
                        printf("%d
",s);
    
                        Update(1,n,1,l,r,s);
                    }
                    else
                    {
                        printf("%d
",c-p.Max);
                    
                        Update(1,n,1,l,r,c-p.Max);
                    }
                }
            }
            else if(!strcmp(str,"state"))
            {
                scanf("%d",&l);
                
                r=++l;
                
                p=Query(1,n,1,l,r,0);
                
                printf("%d
",p.Max);
            }
        }
    }
    return 0;
}


原文地址:https://www.cnblogs.com/juechen/p/5255907.html