zoukankan      html  css  js  c++  java
  • 【关于动态开点线段树】

    动态开点线段树

    首先:

    你需要知道 什么是线段树(我的模板) 及 权值线段树

    动态开点的概念和功能

    在线段树里 其实 动态开点 就和 C++ 里的new()差不多
    思考这样一个问题
    我们有一个权值最大为(1^9)的权值线段树
    我们一算 需要的空间元素个数大概在 (4^9) 直接MLE
    于是你说着出题人毒瘤
    但其实你是不会动态开点
    我们在寻常的线段树中是创造了一个满二叉树 对于一个节点(x) 他的左儿子是 (x * 2) 他的右儿子是 (x * 2 + 1)
    但是如果一个节点创建后没有查询 那么创建它只会增大空间
    所以我们采用动态开点
    只有在一个点被用时 创建它
    就是节点的编号和节点左右儿子的编号都是乱序的,是我们临到使用之时现加上去的。

    代码

    ll Get_Son(long long &pos)
    {
        if(pos==0) pos=++cnt;
        return pos;
    }
    
    void PushUp(long long pos)
    {
        sum[pos]=sum[lson[pos]]+sum[rson[pos]];
    }
    
    void PushDown(long long pos,long long l,long long r)//区间查询用
    {
        sum[Get_Son(lson[pos])]+=(mid-l+1)*Lazy[pos];
        sum[Get_Son(rson[pos])]+=(r-mid)*Lazy[pos];
        Lazy[lson[pos]]+=Lazy[pos];
        Lazy[rson[pos]]+=Lazy[pos];
        Lazy[pos]=0;
    }
    
    void UpZone(long long &pos,long long l,long long r,long long L,long long R,long long C)
    {
        //L,R表示操作区间 , l,r表示当前节点区间 , pos表示当前节点编号
        if(pos==0) pos=++cnt;
        if(Lazy[pos]!=0) PushDown(pos,l,r);//下推标记
        
        if(L<=l && R>=r)//节点区间在操作区间之内,直接返回
        {
            sum[pos]+=(r-l+1)*C;//这个点需要加上区间长度*C
            Lazy[pos]+=C;//用Lazy标记,表示本区间的Sum正确,子区间的Sum仍需要根据Lazy调整
            return;
        }
    
        if(L<=mid) UpZone(lson[pos],l,mid,L,R,C);
        if(R>mid) UpZone(rson[pos],mid+1,r,L,R,C);
        PushUp(pos);
    }
    
    ll Query(long long pos,long long l,long long r,long long L,long long R)
    {
        //L,R表示操作区间 , l,r表示当前节点区间 , pos表示当前节点编号
        if(pos==0) return 0;
        if(Lazy[pos]) PushDown(pos,l,r);//下推标记,否则sum可能不正确
    
        if(L<=l && R>=r)//节点区间在操作区间之内,直接返回
        {
            return sum[pos];
        }
        
        //统计答案
        long long ans=0;
        if(L<=mid) ans+=Query(lson[pos],l,mid,L,R);
        if(R>mid) ans+=Query(rson[pos],mid+1,r,L,R);
        PushUp(pos);
        return ans;
    }
    
  • 相关阅读:
    Java Program to Calculate Standard Deviation
    Basic JavaScript: Counting Cards
    MacBook Pro jdk Installation、Update、Delete
    How to Download and Install Oracle JAVA 8 on Ubuntu 18.04/16.04 LTS
    9扩大你的词汇量:字体和颜色样式
    8添加一些样式:开始学习CSS
    7添加一个“X”到HTML:转到XHTML
    6严格的HTML:遵循标准,合乎规范
    5认识媒体:给网页添加图像
    4Web镇之旅:开始链接
  • 原文地址:https://www.cnblogs.com/dixiao/p/13744221.html
Copyright © 2011-2022 走看看