zoukankan      html  css  js  c++  java
  • 【以前的空间】主席树

    主席树

    周五晚蔡大神讲了下,觉得不是很难的东西,然后就可是敲,发现好像就是个持久化线段树(?!)

    当晚笔记:

    主席树,其实就是多棵可持久化权值线段树

    那什么是可持久化线段树呢?

    如树1中就在子树i,树2中也存在长的一毛一样的子树i’,那么我们完全不用建两棵相同的子树啊,直接树1子节点是i,树2的子节点也是i……(这样还是树么orz)

    何为主席树,

    比如数列【2,3,1,6,4,5】

    那么权值为【1-6】

    然后一树以包括【2】建一棵权值线段树

        二树以包括【2,3】建一棵权值线段树

        三树以包括【2,3,1】建一棵权值线段树

        。。。。。。

        六树以包括【2,3,1,6,4,5】建一棵权值线段树。

    可以发现要建好多棵线段树,还可以发现树i是在树i-1的基础上建的。(这用于以后的修改,先不说)

    然后我们来研究下这些树的性质:

    比如在统计【l,r】中大于y的点有多少个。

        发现树r的信息减掉树l-1的信息,然后就可以得到【l,r】的信息(也可以看成一棵【l,r】的权值线段树)

    至于修改,前面说了,只是在前一个基础上改罢了

    修改操作:简单说就是左树不一样那么就左树改右树还是老树……

    procedure insert(x,ll,rr,old:longint;var new:longint);
    
    var
    
      mid:longint;
    
    begin
    
      inc(tot);
    
      new:=tot;
    
      sum[new]:=sum[old]+1;
    
      if ll=rr then exit;
    
      mid:=(ll+rr)>>1;
    
      if x<=mid then begin
    
        right[new]:=right[old];
    
        insert(x,ll,mid,left[old],left[new]);
    
      end
    
      else begin
    
        left[new]:=left[old];
    
        insert(x,mid+1,rr,right[old],right[new]);
    
      end;
    
    end;
    View Code

    要是碰到修改怎么办……

    如果从左到右重建,就要修改好多棵线段树。但是发现树i保存的是【1,i】的信息,这东西不就是信息的前缀和?前缀和在单点修改时有个神器bit,使修改n询问1变为修改logn询问logn。

    单点修改

    procedure add(x,y,z:longint);
    
    begin
    
      while x<=n do begin
    
        change(y,z,1,total,root[x],root[x]);
    
        inc(x,lowbit(x));
    
      end;
    
    end;
    View Code

    把insert稍微改装一下变成change,多了个参数y,当是删除时y=-1,加是y=1.(其实就是bit套主席树而已啦)

    然后区间的还没写过。

    然后主席树各种速度碾压好可怕。

    然后我的主席树好像写的很丑?

    最后是题目汇总:

    1901: Zju2112 Dynamic Rankings

    3524: [Poi2014]Couriers

    3207: 花神的嘲讽计划Ⅰ

    2653: middle

    3439: Kpm的MC密码(略欢乐,倒建trie似乎在usaco就见过,还有出题人提供的题解有很强的误导向,他是专门写复杂来吓我们的!然后小问题调了好久)

  • 相关阅读:
    mac下给git://协议设置代理Proxy
    安卓手机中wifi密码查看器,查看wifi密码教程
    坑爹啊!gradle 2.1构建android出现错误的解决方案
    php-fpm开启报错-ERROR: An another FPM instance seems to already listen on /tmp/php-cgi.sock详解
    git rebase 还是 merge的使用场景最通俗的解释
    git rebase 与 git merge 的区别
    zend opcache的最佳设置(仅做参考)
    PHP7.3 报错: A non well formed numeric value encountered
    关于PHP.ini的opcache中opcache.revalidate_freq参数设置测试报告
    微信小程序登录实现,前端+后端PHP代码(前端获得CODE,后端获取微信用户的OPEN ID 和 UNION ID)
  • 原文地址:https://www.cnblogs.com/Macaulish/p/6492135.html
Copyright © 2011-2022 走看看