题目链接

【BZOJ传送门】
【洛谷传送门】

题解

终于学会了可持久化trie树了。感觉并不是特别的难。
因为可持久化,那么我们就考虑动态开点的trie树。
都知道异或操作是有传递性的,那么我们就维护一个前缀异或和。
【最长异或距离】
可以参考以上这一道题目的贪心策略。
每次找到另外一边的(说的清楚一点就是每一次找字典树的儿子都找异或的数当前这一位的异或1的值),这样可以保证疑惑后答案最大。
参照主席树的区间最小的求法:【洛谷的模板】
每一次我们就查找root[l - 1] ~ root[r]区间内的答案就可以了。


一开始不理解可持久化01字典树的原因是因为我不知道为什么字典树里面需要有31这个东西
然后我就发现了这个31其实就是普通字典树里面的字符串的长度的意思。
真的是石乐志了。qwq


那么可持久化01trie的模板如下

插入操作

  1. void ins(int &rt, int pre, int val, int len) {
  2. rt = ++ tot; int k = rt;
  3. for (int i = len; ~i; i --) {
  4. ch[k][0] = ch[pre][0]; ch[k][1] = ch[pre][1]; cnt[k] = cnt[pre] + 1;
  5. int p = (val >> i) & 1;
  6. ch[k][p] = ++ tot;
  7. k = ch[k][p]; pre = ch[pre][p];
  8. }
  9. cnt[k] = cnt[pre] + 1;
  10. }

其他的操作和普通的字典树是一样的。


代码

  1. #include <bits/stdc++.h>
  2. #pragma GCC optimize(2)
  3. #define ms(a, b) memset(a, b, sizeof(a))
  4. #define ll long long
  5. #define ull unsigned long long
  6. #define ms(a, b) memset(a, b, sizeof(a))
  7. #define inf 0x3f3f3f3f
  8. #define db double
  9. #define Pi acos(-1)
  10. #define eps 1e-8
  11. #define N 600005
  12. using namespace std;
  13. template <typename T> T power(T x, T y, T mod) { x %= mod; T res = 1; for (; y; y >>= 1) { if (y & 1) res = (res * x) % mod; x = (x * x) % mod; } return res; }
  14. template <typename T> void read(T &x) {
  15. x = 0; T fl = 1; char ch = 0;
  16. for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') fl = -1;
  17. for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
  18. x *= fl;
  19. }
  20. template <typename T> void write(T x) {
  21. if (x < 0) x = -x, putchar('-');
  22. if (x > 9) write(x / 10); putchar(x % 10 + '0');
  23. }
  24. template <typename T> void writeln(T x) { write(x); puts(""); }
  25. struct L_Trie {
  26. int ch[N * 40][2], cnt[N * 40], tot;
  27. void ins(int &rt, int pre, int val, int len) {
  28. rt = ++ tot; int k = rt;
  29. for (int i = len; ~i; i --) {
  30. ch[k][0] = ch[pre][0]; ch[k][1] = ch[pre][1]; cnt[k] = cnt[pre] + 1;
  31. int p = (val >> i) & 1;
  32. ch[k][p] = ++ tot;
  33. k = ch[k][p]; pre = ch[pre][p];
  34. }
  35. cnt[k] = cnt[pre] + 1;
  36. }
  37. int query(int x, int y, int val, int len) {
  38. int res = 0;
  39. for (int i = len; ~i; i --) {
  40. int p = (val >> i) & 1;
  41. if (cnt[ch[y][p ^ 1]] - cnt[ch[x][p ^ 1]] > 0) { res += (1 << i); x = ch[x][p ^ 1]; y = ch[y][p ^ 1]; }
  42. else x = ch[x][p], y = ch[y][p];
  43. }
  44. return res;
  45. }
  46. } trie;
  47. int root[N], sumxor[N];
  48. char opt[5];
  49. int n, m;
  50. int main() {
  51. read(n); read(m);
  52. trie.ins(root[0], root[0], 0, 31);
  53. for (int i = 1; i <= n; i ++) {
  54. int x; read(x);
  55. sumxor[i] = sumxor[i - 1] ^ x;
  56. trie.ins(root[i], root[i - 1], sumxor[i], 31);
  57. }
  58. for (int i = 1; i <= m; i ++) {
  59. scanf("%s", opt); int x, l, r;
  60. if (opt[0] == 'A') {
  61. read(x); ++ n; sumxor[n] = sumxor[n - 1] ^ x;
  62. trie.ins(root[n], root[n - 1], sumxor[n], 31);
  63. }
  64. else {
  65. read(l); read(r); read(x); l --; r --;
  66. printf("%d\n", trie.query(root[l - 1], root[r], x ^ sumxor[n], 31));
  67. }
  68. }
  69. return 0;
  70. }

⌈洛谷4735⌋⌈BZOJ3261⌋最大异或和【可持久化01Trie】的更多相关文章

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

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

  2. BZOJ 4103 [Thusc 2015]异或运算 (可持久化01Trie+二分)

    题目大意:给你一个长方形矩阵,位置$i,j$上的数是$a_{i}\;xor\;b_{j}$,求某个子矩阵内第$K$大的值 最先想的是二分答案然后验证,然而是$O(qnlogmloga_{i})$,不出 ...

  3. BZOJ 3689 异或之 (可持久化01Trie+堆)

    题目大意:给你一个序列,求出第$K$大的两两异或值 先建出来可持久化$01Trie$ 用一个$set$/堆存结构体,存某个异或对$<i,j>$的第二关键字$j$,以及$ai\;xor\;a ...

  4. BZOJ 3261 最大异或和 (可持久化01Trie)

    题目大意:让你维护一个序列,支持在序列末插入一个数,支持询问$[l,r]$区间内选择一个位置$p$,使$xor\sum_{i=p}^{n}a_{i}$最大 可持久化$01Trie$裸题,把 区间异或和 ...

  5. 洛谷 [P2420] 让我们异或吧

    某两点之间的路径上所有边权的异或值即dis1^dis2--^disn. 由于x^y^y=x,所以dfs预处理出每一点到根节点的异或值,对于每次询问,直接输出 disu^disv. #include & ...

  6. 洛谷P4551 最长异或路径

    传送门:https://www.luogu.org/problem/show?pid=4551 在看这道题之前,我们应懂这道题怎么做:给定n个数和一个数m,求m和哪一个数的异或值最大. 一种很不错的做 ...

  7. 洛谷 P2420 让我们异或吧 解题报告

    P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ...

  8. 【洛谷P4735】最大异或和

    题目大意:给定一个长度为 N 的序列,支持两个操作:在序列末尾添加一个新的数字,查询序列区间 \([l,r]\) 内使得 \(a_p\oplus a_{q+1}\oplus ... a_N\oplus ...

  9. 2018.10.26 洛谷P4551 最长异或路径(01trie)

    传送门 直接把每个点到根节点的异或距离插入01trie. 然后枚举每个点在01trie上匹配来更新答案就行了. 代码: #include<iostream> #include<cst ...

随机推荐

  1. CentOS 6.5 手动rpm包安装gcc、g++

    摘自:https://blog.csdn.net/lichen_net/article/details/70211204 mount CentOS的安装光盘,然后先后安装 rpm -ivh ppl-0 ...

  2. 自己实现数据结构系列四---Queue

    一.代码部分 1.定义接口: public interface Queue<E> { void enqueue(E e); E dequeue(); E getFront(); int g ...

  3. HTTPS的SSL证书配置

    SSL证书 TOMCAT7.0部署_百度经验https://jingyan.baidu.com/article/7082dc1c65066be40a89bda8.html SSL证书安装指引 - 青春 ...

  4. Docker 安装和配置

    #centos 6 需要另外安装 yum install lxc libcgroup device-mapper-ecent-libs 推荐centos7 安装深事#centos 7 直接安装就好yu ...

  5. PyCharm3.0默认快捷键

    PyCharm3.0默认快捷键(翻译的) 1.编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性) Ctrl + Alt + Space 快速导入任意类 Ctrl + S ...

  6. vue传参二

    <template> <ul> <li v-for="(value,key,index) in list" :key="index" ...

  7. Oracle pivot行转列函数案例

    with temp as( select '湖北省' province,'武汉市' city,'第一' ranking from dual union all select '湖北省' provinc ...

  8. phpstorm显示页面不停的在indexing转圈中,并且文件名还一直在刷新

    打开 File下的 Invalidate Caches / Restart...下的 Invalidate and Restart. 便可以了 ......

  9. groovy安装 ideal

    参考:https://blog.csdn.net/newbie_907486852/article/details/80879745 (1) 首先下载groovy: https://gradle.or ...

  10. Chrome 75 & lazy-loading

    Chrome 75 & lazy-loading https://addyosmani.com/blog/lazy-loading/ https://chromestatus.com/feat ...