• 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;
    }
    


  • 相关阅读:
    树状数组
    1424:【例题3】喷水装置
    Matrix (二分套二分
    素数筛
    快速幂
    CentOS6/7-防火墙管理
    Ubuntu15.04 python升级到python-3.6.x
    查看Linux系统用户登录日志
    [shell]查找网段内可用IP地址
    最小化安装Linux的常用配置整理
  • 原文地址:https://www.cnblogs.com/juechen/p/5255907.html
Copyright © 2020-2023  润新知