• HDU 1556【线段树区间更新】


    这篇lazy讲的很棒:
    https://www.douban.com/note/273509745/
    if(tree[rt].l == l && r == tree[rt].r)
    这里就是用到Lazy思想的关键时刻 正如上面说提到的,这里首先更新该节点的sum[rt]值,
    然后更新该节点具体每个数值应该加多少即add[rt]的值,
    注意此时整个函数就运行完了,直接return,而不是还继续向子节点继续更新,
    这里就是Lazy思想,暂时不更新子节点的值。

    那么什么时候需要更新子节点的值呢?
    答案是在某部分update操作的时候需要用到那部分没有更新的节点的值的时候,
    这时就掉用PushDown()函数更新子节点的数值。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    struct asd{
        int left,right;
        int ad;
        int w;
    };
    asd q[N*4];
    
    void build(int num,int L,int R)
    {
        q[num].left=L;
        q[num].right=R;
        if(L==R)
        {
            q[num].w=q[num].ad=0;
            return;
        }
        build(2*num,L,(L+R)/2);
        build(2*num+1,(L+R)/2+1,R);
        q[num].w=q[num].ad=0;
    }
    int ss(int num)
    {
        return q[num].right-q[num].left+1;
    }
    void Pushdown(int num)
    {
        if(q[num].ad)
        {
            q[num*2].w+=q[num].ad*(ss(2*num));
            q[num*2+1].w+=q[num].ad*(ss(2*num+1));
            q[num*2].ad+=q[num].ad;
            q[num*2+1].ad+=q[num].ad;
            q[num].ad=0;
        }
    }
    void Pushup(int num)
    {
        q[num].w=q[2*num].w+q[2*num+1].w;
    }
    void update(int num,int s,int t)
    {
        if(s==q[num].left&&q[num].right==t)
        {
            q[num].w+=t-s+1;
            q[num].ad+=1;
            return;
        }
        if(q[num].left==q[num].right)
            return;
        Pushdown(num);
        int mid=(q[num].right+q[num].left)/2;
        if(mid>=t)
            update(2*num,s,t);
        else if(mid<s)
            update(2*num+1,s,t);
        else
        {
            update(2*num,s,mid);
            update(2*num+1,mid+1,t);
        }
        Pushup(num);
    }
    int query(int num,int s,int t)
    {
        if(s==q[num].left&&q[num].right==t)
            return q[num].w;
        Pushdown(num);
        int ans=0;
        int mid=(q[num].right+q[num].left)/2;
        if(mid>=t)
            ans+=query(2*num,s,t);
        else if(mid<s)
            ans+=query(2*num+1,s,t);
        else
            ans+=query(2*num,s,mid)+query(2*num+1,mid+1,t);
        return ans;
    }
    
    int main()
    {
        int n;
        while(~scanf("%d",&n)&&n)
        {
            int x,y;
            build(1,1,n);
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&x,&y);
                update(1,x,y);
            }
            for(int i=1;i<=n;i++)
            {
                if(i>1) printf(" ");
                printf("%d",query(1,i,i));
            }
            puts("");
        }
        return 0;
    }
    
    /*
    6
    1 6
    1 6
    1 6
    1 3
    2 5
    3 6
    */
  • 相关阅读:
    获取windows所有用户名
    windbg内存查看(d*)
    Windbg查看调用堆栈(k*)
    Windbg调试互斥体(Mutex)死锁
    Windbg调试关键区(CriticalSection)死锁
    "R6002 floating point support not loaded"错误
    由可变参数引起的崩溃
    【Dubbo源码学习】负载均衡算法(2)-轮询算法的实现
    jdk1.8源码解析(1):HashMap源码解析
    Java annotation浅析
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934787.html
Copyright © 2020-2023  润新知