zoukankan      html  css  js  c++  java
  • hdu 3954(线段树的特殊lazy操作-更新时才遍历!)

      和经典的线段树区间lazy操作相比,区间传递的是经验系数,每个点对系数的反应是不一样的,所以向下传递的时机有所改变,不但在区间被剖分时要向下释放,在该区间有某个点要升级的时候也要释放,因为此时用区间的lazy值叠加的话会影响结果,所以此时要释放lazy,lazy只有在这个区间的点都没到达升级门槛时才可以叠加。 

     

    #include<cstdlib>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<stack>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define pb push_back
    #define mp make_pair
    #define ULL unsigned long long
    #define LL long long
    #define inf 1e9
    #define eps 1e-7
    #define N 10009
    using namespace std;
    int m,n,T,t,q,k;
    int need[20],ql,qr,e;
    int ex[N<<2],lel[N<<2],minx[N<<2],lazy[N<<2];
    /*
    ex[o]:最大经验。没有加父节点的lazy[o].
    lel[o]:最大水平。
    minx[o]:区间升级所需最小的系数!(升级时才向下遍历-减小复杂度)
    lazy[o]:区间增加的个数。
    复杂度:大约O(kn+qlgn);
    */
    void build(tree)
    {
        lel[o]=1;
        ex[o]=lazy[o]=0;
        minx[o]=need[2];
        if(l<r)
        {
            int mid=(l+r)>>1;
            build(lson);
            build(rson);
        }
    }
    void init()
    {
        build(1,1,n);
        return ;
    }
    void pushup(int o)//只需更新父节点!
    {
        ex[o]=max(ex[lo],ex[ro]);
        lel[o]=max(lel[lo],lel[ro]);
        minx[o]=min(minx[lo],minx[ro]);
    }
    void push_down(int o)//push_down时,修改子节点!更方便!
    {
        if(lazy[o])
        {
            lazy[lo]+=lazy[o];
            lazy[ro]+=lazy[o];
            ex[lo]+=lazy[o]*lel[lo];
            ex[ro]+=lazy[o]*lel[ro];
            minx[lo]-=lazy[o];
            minx[ro]-=lazy[o];
    
            lazy[o]=0;
        }
    }
    void update(tree)
    {
        if(l==r)
        {
            ex[o]+=lel[o]*(e);
            while(ex[o]>=need[lel[o]+1])lel[o]++;
            minx[o]=(need[lel[o]+1]-ex[o]+lel[o]-1)/lel[o];//+1
        }
        else
        {
            int mid=(l+r)>>1;
            if(ql<=l&&qr>=r)
            {
                if(minx[o]<=e)
                {
                    push_down(o);
                    if(ql<=mid)
                        update(lson);
                    if(qr>mid)
                        update(rson);
                    pushup(o);
                }
                else
                {
                    ex[o]+=e*lel[o];
                    lazy[o]+=e;
                    minx[o]-=e;
                }
            }
            else
            {
                push_down(o);
                if(ql<=mid)
                    update(lson);
                if(qr>mid)
                    update(rson);
                pushup(o);
            }
        }
    }
    int query(tree)
    {
        if(ql<=l&&qr>=r)
        {
            return ex[o];
        }
        else
        {
            push_down(o);
            int mid=(l+r)>>1;
            int ans=0;
            if(ql<=mid)ans=max(ans,query(lson));
            if(qr>mid)ans=max(ans,query(rson));
            pushup(o);
            return ans;
        }
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
        int ncase=0;
        need[1]=0;
        scanf("%d",&T);
        char str[10];
        while(T--)
        {
            scanf("%d%d%d",&n,&k,&q);
            for(int i=2; i<=k; ++i)
                scanf("%d",&need[i]);
            need[k+1]=inf;
            init();
            printf("Case %d:
    ",++ncase);
            while(q--)
            {
                scanf("%s",str);
                if(str[0]=='W')
                {
                    scanf("%d%d%d",&ql,&qr,&e);
                    update(1,1,n);
                }
                else
                {
                    scanf("%d%d",&ql,&qr);
                    printf("%d
    ",query(1,1,n));
                }
            }
            puts("");
        }
        return 0;
    }

     

     

  • 相关阅读:
    mysql密码重置
    利用python生成定制二维码
    totnado前后端分离跨域设置
    supervisor详解
    redis持久化常识和配置
    redis数据的备份与恢复
    supervisor下更换源文件报错
    EF5框架封装
    IEnumerable和IEnumerator 详解
    心宽,路自宽
  • 原文地址:https://www.cnblogs.com/sbaof/p/3369284.html
Copyright © 2011-2022 走看看