我跟可持久化数据结构杠上了 \(QwQ\) 。三天模拟赛考了两次可持久化数据结构(主席树、可持久化0-1Trie树),woc。


目录:

  • 个人理解
  • 时空复杂度分析
  • 例题及简析

一、个人理解

可持久化0-1Trie树,是一种可以快速查询区间异或信息的高级数据结构。

它的主要思想和主席树相同,即保存每次插入操作的历史版本,来快速查询区间的异或信息。

0-1Trie树和平常写的strTrie树相同,都是维护前缀信息的数据结构。不同点只有一个,就是0-1Trie树是维护一个0-1串。可持久化0-1Trie树运用了贪心的思想,即将序列里的 \(X\) 按二进制为拆分,若当前 \(X_i\) (指 \(X\) 二进制拆分后的第 \(i\) 位)是1,我们就往0-1Trie树的0边走;反之就往0-1Trie树的1边走。

可持久化0-1Trie树与主席树相同,也需要动态开点。

注意:维护区间异或信息的不止可持久化0-1Trie树一种,还有线性基等。


二、时空复杂度分析:

  1. 时间复杂度:

    与普通0-1Trie树相同:\(O(n\log n)\) 。

    :strTrie树的时间复杂度是 \(O(n)\) ,是一种典型的以时间换空间的算法。

  2. 空间复杂度:

    与普通的0-1Trie树相同:\(O(\min\{n\log |f(a_i)|,|f(a_i)|\})\) ( \(|f(a_i)|\) 为值域)。注意常数为 \(2^5\) (1<<5)。


三、例题及简析

  1. P4735 最大异或和

    Description:

    给定数列 \(\{a_n\}\) ,支持两种操作:

    • 在数列尾添加一个数 \(x\) ,数列长度变成 \(n+1\) ;

    • 给定闭区间 \([l,r]\) 和一个数 \(x\) ,求:

      \[\max_{i=l}^{r}\left \{\left(\bigoplus_{j=i}^{n}a_j \right)\bigoplus x\right \}
      \]

    Method:

    定义 \(Xorsum_i\) 为 \(\bigoplus_{i=1}^{n}a_i\) ,即前缀异或和。我们显然可以得到

    \[\left(\bigoplus_{i=pos}^{n}a_i\right)\bigoplus x=Xorsum_{pos-1}\bigoplus Xorsum_n \bigoplus x
    \]

    :\(x\bigoplus x=0\) , \(x \bigoplus 0=x\) 。

    我们发现 \(Xorsum_n\bigoplus x\) 是一个定值,我们只需要维护 \(Xorsum_{pos-1}\) 即可。

    考虑用可持久化0-1Trie树维护。与主席树思路相同 ,我们建立 \(n+1\) 个版本的0-1Trie树,查询的时候运用贪心的思路即可。

    可持久化线段树同样支持“前缀和”的思想,我们最后只需要在第 \(r\) 个版本的0-1Trie树上查找 \(l\) 位置即可。

    本题毒瘤卡常,本人人丑常数大,用了fread等各种卡常操作才通过。并且由于luogu评测姬的原因(大雾,已经通过的代码又会T掉woc。卡不过的话,开o2吧。

    Code:

    1. #include<bits/stdc++.h>
    2. #define Maxn 600010
    3. #define Maxdep 23
    4. #define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    5. char buf[1<<21],*p1=buf,*p2=buf;
    6. inline void read(int &x)
    7. {
    8. int f=1;x=0;char s=getchar();
    9. while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    10. while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    11. x*=f;
    12. }
    13. int n,m;
    14. int sum[Maxn];
    15. struct trie
    16. {
    17. trie *chd[2];
    18. int symbl;
    19. trie()
    20. {
    21. for(int i=0;i<2;i++) chd[i]=NULL;
    22. symbl=0;
    23. }
    24. }*root[Maxn],tree[Maxn<<5],*tail;
    25. void Init(){tail=tree;}
    26. void build(trie *&p,int dep)
    27. {
    28. p=new (tail++)trie();
    29. if(dep<0) return ;
    30. build(p->chd[0],dep-1);
    31. }
    32. void update(trie *&p,trie *flag,int dep,int i)
    33. {
    34. p=new (tail++)trie();
    35. if(flag) *p=*flag;
    36. if(dep<0) return (void)(p->symbl=i);
    37. int tmp=(sum[i]>>dep)&1;//判断是1还是0
    38. if(!tmp) update(p->chd[0],flag?flag->chd[0]:NULL,dep-1,i);
    39. else update(p->chd[1],flag?flag->chd[1]:NULL,dep-1,i);
    40. if(p->chd[0]) p->symbl=std::max(p->symbl,p->chd[0]->symbl);
    41. if(p->chd[1]) p->symbl=std::max(p->symbl,p->chd[1]->symbl);
    42. }
    43. int query(trie *p,int x,int dep,int limit)
    44. {
    45. if(dep<0) return sum[p->symbl]^x;
    46. int tmp=(x>>dep)&1;
    47. if(p->chd[tmp^1]&&p->chd[tmp^1]->symbl>=limit) return query(p->chd[tmp^1],x,dep-1,limit);
    48. return query(p->chd[tmp],x,dep-1,limit);
    49. }
    50. signed main()
    51. {
    52. Init();
    53. read(n),read(m);
    54. build(root[0],Maxdep);
    55. for(int i=1,x;i<=n;i++)
    56. {
    57. read(x);
    58. sum[i]=sum[i-1]^x;
    59. update(root[i],root[i-1],Maxdep,i);
    60. }
    61. for(int i=1;i<=m;i++)
    62. {
    63. char ch=getchar();
    64. while(ch!='A'&&ch!='Q') ch=getchar();
    65. if(ch=='A')
    66. {
    67. int x;
    68. read(x);
    69. n++;
    70. sum[n]=sum[n-1]^x;
    71. update(root[n],root[n-1],Maxdep,n);
    72. continue;
    73. }
    74. if(ch=='Q')
    75. {
    76. int l,r,x;
    77. read(l),read(r),read(x);
    78. int ans=query(root[r-1],sum[n]^x,Maxdep,l-1);
    79. printf("%d\n",ans);
    80. continue;
    81. }
    82. }
    83. return 0;
    84. }

可持久化0-1Trie树的更多相关文章

  1. 【可持久化0/1Trie】【P4735】最大异或和

    Description 给定一个长度为 \(n\) 的序列 \(A\),有 \(m\) 次操作,每次要么在序列尾部再添加一个数,将序列长度 \(n\) 加一,要么给进行一次查询,给定查询参数 \(l, ...

  2. Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (0/1-Trie树)

    Vasiliy's Multiset 题目链接: http://codeforces.com/contest/706/problem/D Description Author has gone out ...

  3. [Codeforces757G]Can Bash Save the Day?——动态点分治(可持久化点分树)

    题目链接: Codeforces757G 题目大意:给出一棵n个点的树及一个1~n的排列pi,边有边权,有q次操作: 1 l r x 求 $\sum\limits_{i=l}^{r}dis(p_{i} ...

  4. 51nod 1295 XOR key 可持久化01字典树

    题意 给出一个长度为\(n\)的正整数数组\(a\),再给出\(q\)个询问,每次询问给出3个数,\(L,R,X(L<=R)\).求\(a[L]\)至\(a[R]\)这\(R-L+1\)个数中, ...

  5. 【CF757G】Can Bash Save the Day? 可持久化点分树

    [CF757G]Can Bash Save the Day? 题意:给你一棵n个点的树和一个排列${p_i}$,边有边权.有q个操作: 1 l r x:询问$\sum\limits_{i=l}^r d ...

  6. HDU 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序

    题意 给一颗\(n\)个节点的带点权的树,以\(1\)为根节点,\(q\)次询问,每次询问给出2个数\(u\),\(x\),求\(u\)的子树中的点上的值与\(x\)异或的值最大为多少 分析 先dfs ...

  7. 洛谷P3919 【模板】可持久化数组 [主席树]

    题目传送门 可持久化数组 题目描述 如题,你需要维护这样的一个长度为 $N$ 的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对 ...

  8. P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树

    $ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...

  9. luogu 2483 K短路 (可持久化左偏树)

    题面: 题目大意:给你一张有向图,求1到n的第k短路 $K$短路模板题 假设整个图的边集为$G$ 首先建出以点$n$为根的,沿反向边跑的最短路树,设这些边构成了边集$T$ 那么每个点沿着树边走到点$n ...

  10. luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树

    LINK:字符串树 先说比较简单的正解.由于我没有从最简单的考虑答案的角度思考 所以... 下次还需要把所有角度都考察到. 求x~y的答案 考虑 求x~根+y~根-2*lca~根的答案. 那么问题变成 ...

随机推荐

  1. 类例程_c#战斗程序(窗体版)

    战士类代码: class Fight { String name; int attack, speed, crit, armor;// 生命.攻击力,攻速,暴击,护甲 public int life; ...

  2. 读《计算机系统要素:从零开始构建现代计算机》的思考:CodeGen

    掌握目标语言的使用.编写 是非常重要的!!! 如果你要实现的Jack语言编译器是把Jack语言代码编译成虚拟机VM代码.或者直接成汇编代码,要完成源代码中unit A——> 目标语言代码转写此u ...

  3. AppiumLibrary 关键字文档

    http://serhatbolsu.github.io/robotframework-appiumlibrary/AppiumLibrary.html#Start%20Activity

  4. sql语句技巧

    应用场景:当sql 语句中where后面的条件字段为空的时候,条件不存在 eg:根据传入的参数,从student表中查询数据,参数包含姓名(name 必有),年龄(age 不一定有),性别(gende ...

  5. Beego 学习笔记15:布局页面

    页面布局 1>     一个html页面由:head部分,body部分,内部css,内部js,外联css,外联的js这几部分组成.因此,一个布局文件也就需要针对这些进行拆分. 2>     ...

  6. JavaScript 之 location 对象

    一.location 对象 location 对象是 window 对象下的一个属性,使用的时候可以省略 window 对象. 常用属性: location.href = 'http://www.ba ...

  7. React 性能优化之组件动态加载(react-loadable)

    React 项目打包时,如果不进行异步组件的处理,那么所有页面所需要的 js 都在同一文件中(bundle.js),整个js文件很大,从而导致首屏加载时间过长. 所有,可以对组件进行异步加载处理,通常 ...

  8. vue 指令中el 的 parentNode 为空的问题

    在项目中,突然发现在用vue指令的时候,发现元素el的父元素parentNode变成了null. 代码: if (el.parentNode && !Vue.prototype.$_h ...

  9. 逻辑回归 之 Logist 推导

    Logist从概率角度认识 可以咱学校教材大二版的<> - 山大版, 来整一波, 为了简化推导形式呢, 这里就假设2个样本空间的形式来展开, 基于(条件概率) 全概率与贝叶斯 作为核心. ...

  10. NumPy 之 面向数组编程

    import numpy as np Using NumPy arrays enables you to express many kinds of data processing tasks as ...