zoukankan      html  css  js  c++  java
  • 可持久化线段树,可持久化权值线段树(主席树)

    前言:

    今天听了钟长者的课,听了分块,莫队,可持久化线段树,主席树.....因为明天没有模拟赛,所以整理一下。

    等等,为什么可持久化线段树和主席树分开了,我一直以为它们是一个数据结构,但钟长者说并不是。

    钟长者言:“可持久化线段树是线段树的一个托展,主席树是可持久化线段树的一个具体应用。”

    那就跟随钟长者的脚步从可持久化线段树开始,


    一,可持久化线段树

    所谓可持久化数据结构,就是要记录在某次操作之后的状态,比如对于一个普通的线段树,我们有m次

    操作,但对于第i次操作之后(1<=i<=m),我们就不知道i之前线段树的样子了,可持久化线段树就是

    让我们记住它之前的样子。

    1,一种暴力的做法

    那么,对于上述的问题情境,有一种很简单的做法啊,就是对于每次操作i后我们都建一棵线段树,这样

    如果我们询问某次操作之后的数据,直接查询对应的线段树即可。

    2,对于暴力做法的优化

    在上述做法中,我们不难发现,无论是时间还是空间都不是很优,那么我们怎么优化呢,在此我们只考虑存在

    单点修改的情况,不考虑有区间修改,(因为博主菜QwQ),我们会发现对于每个单点修改,很像树状数组的一点,

    只会影响到含有那个点区间的线段树上的节点,那么我们不难想到,我们对于第i次修改操作,只需要记一下它所

    影响的那条链即可,然后我们将这条链上的点连回原树,就完成了可持久化线段树。

    3,可持久化线段树的基本操作

    a.建树

    因为要重新记录一下受影响的链,所以我们不能像线段树那样对于每个节点编号,我们在建树的时候要记一下

    每个点的左二子和右儿子的编号。

     1 struct node
     2 {
     3     int lc,rc;
     4     int sum;
     5     node()
     6     {
     7         lc=rc=sum=0;
     8     }
     9 };
    10 node tree[maxn*5];
    11 inline int build(int l,int r)
    12 {
    13     int k=++cnt;
    14     if(l==r)
    15     {
    16         tree[k].sum=num[l];
    17         return k;
    18     }
    19     int mid=(l+r)>>1;
    20     tree[k].lc=build(l,mid); tree[k].rc=build(mid+1,r);
    21     tree[k].sum=tree[tree[k].lc].sum+tree[tree[k].rc].sum;
    22     return k;
    23 }

    b.修改操作

    与普通的线段树不同,可持久化线段树要记下第i次操作后情况,所以对于第i次操作影响的节点,我们都

    建一个新的点,然后将不变的信息连回这条链上即可。

     1 inline int modify(int rt,int l,int r,int p,int v)
     2 {
     3     int new_rt=++cnt;
     4     tree[cnt]=tree[rt];//先把原信息复制上,再修改即可实现
     5     if(l==r)
     6     {
     7         tree[new_rt].sum+=v;
     8         return new_rt;
     9     }
    10     int mid=(l+r)>>1;
    11     if(p<=mid) tree[new_rt].lc=modify(tree[rt].lc,l,mid,p,v);
    12     else tree[new_rt].rc=modify(tree[st].rc,mid+1,r,p,v); 
    13     tree[new_rt].sum=tree[tree[new_rt].lc].sum+tree[tree[new_rt].rc].sum;
    14     return new_rt;
    15 }

    c.查询操作

    同线段树的基础操作一样,只需要从要查询到的时间对应的树根开始查询即可。

  • 相关阅读:
    Mybatis主配置文件常见使用讲解
    Mybatis导入原生配置文件
    分页查询时,使用cookie保存上次的查询条件。jQuery实现方法以及中间遇到的坑
    jQuery实现checkbox即点即改,批量计数,以及中间遇到的坑
    ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。
    SpringMVC的Controller
    Spring MVC执行原理和基于Java的配置过程
    集成学习综述笔记
    generalization error
    Failed to install 'unknown package' from GitHub: schannel: failed to receive handshake, SSL/TLS connection failed
  • 原文地址:https://www.cnblogs.com/Hoyoak/p/11628883.html
Copyright © 2011-2022 走看看