zoukankan      html  css  js  c++  java
  • 可持久化线段树

    每次进行单点修改后,会新增(log n)个新节点,即每次更改的结点数为树的高度

    增加的非叶子结点一个儿子是其他版本的节点,另一个儿子是连向新节点

    空间复杂度为(O(n+m log n))

    (code)

    void build(int L,int R,int &cur)
    {
    	cur=++tree_cnt;
    	if(L==R)
    	{
    		val[cur]=a[L];
    		return;
    	}
    	int mid=(L+R)>>1;
    	build(L,mid,ls[cur]);
    	build(mid+1,R,rs[cur]);
    }
    void modify(int L,int R,int pos,int v,int pre,int &cur)
    {
    	cur=++tree_cnt;
    	ls[cur]=ls[pre],rs[cur]=rs[pre];
    	val[cur]=val[pre];
    	if(L==R)
    	{
    		val[cur]=v;
    		return;
    	}
    	int mid=(L+R)>>1;
    	if(pos<=mid) modify(L,mid,pos,v,ls[pre],ls[cur]);
    	if(pos>mid) modify(mid+1,R,pos,v,rs[pre],rs[cur]);
    }
    int query(int L,int R,int pos,int cur)
    {
    	if(L==R) return val[cur];
    	int mid=(L+R)>>1;
    	if(pos<=mid) return query(L,mid,pos,ls[cur]);
    	if(pos>mid) return query(mid+1,R,pos,rs[cur]);
    }
    

    标记永久化实现区间加区间查询

    (code:)

    void modify(int L,int R,int l,int r,ll v,int &cur)
    {
        int x=++tree_cnt;
        ls[x]=ls[cur],rs[x]=rs[cur],add[x]=add[cur];
        sum[x]=sum[cur]+v*(min(R,r)-max(L,l)+1),cur=x;
        if(L<=l&&R>=r)
        {
            add[cur]+=v;
            return;
        }
        if(L<=mid) modify(L,R,l,mid,v,ls[cur]);
        if(R>mid) modify(L,R,mid+1,r,v,rs[cur]);
    }
    ll query(int L,int R,int l,int r,int cur)
    {
        if(L<=l&&R>=r) return sum[cur];
        ll ans=add[cur]*(min(R,r)-max(L,l)+1);
        if(L<=mid) ans+=query(L,R,l,mid,ls[cur]);
        if(R>mid) ans+=query(L,R,mid+1,r,rs[cur]);
        return ans;
    }
    
  • 相关阅读:
    Linux Command
    sql查询将列里面的值替换为别的值但是实际值不变
    MY_SQLCode
    ComboBox设置Text属性
    WPF bmp和二进制转换
    C#中打开文件、目录、保存窗口
    WPF实现右键菜单
    BarTender SDK 实现调用模板条码打印
    VS Code非英语版本连接TFS错误解决方案
    DBeaver连接达梦数据库
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229512.html
Copyright © 2011-2022 走看看