可持久化线段树

久未见 提交于 2020-01-22 21:03:58

每次进行单点修改后,会新增\(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]);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!