题目链接

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

题解

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


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


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

插入操作

void ins(int &rt, int pre, int val, int len) {
    rt = ++ tot; int k = rt;
    for (int i = len; ~i; i --) {
        ch[k][0] = ch[pre][0]; ch[k][1] = ch[pre][1]; cnt[k] = cnt[pre] + 1;
        int p = (val >> i) & 1;
        ch[k][p] = ++ tot;
        k = ch[k][p]; pre = ch[pre][p];
    }
    cnt[k] = cnt[pre] + 1;
}

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


代码

#include <bits/stdc++.h>
#pragma GCC optimize(2)
#define ms(a, b) memset(a, b, sizeof(a))
#define ll long long
#define ull unsigned long long
#define ms(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
#define db double
#define Pi acos(-1)
#define eps 1e-8
#define N 600005
using namespace std;
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; }
template <typename T> void read(T &x) {
    x = 0; T fl = 1; char ch = 0;
    for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') fl = -1;
    for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
    x *= fl;
}
template <typename T> void write(T x) {
    if (x < 0) x = -x, putchar('-');
    if (x > 9) write(x / 10); putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) { write(x); puts(""); }
struct L_Trie {
    int ch[N * 40][2], cnt[N * 40], tot;
    void ins(int &rt, int pre, int val, int len) {
        rt = ++ tot; int k = rt;
        for (int i = len; ~i; i --) {
            ch[k][0] = ch[pre][0]; ch[k][1] = ch[pre][1]; cnt[k] = cnt[pre] + 1;
            int p = (val >> i) & 1;
            ch[k][p] = ++ tot;
            k = ch[k][p]; pre = ch[pre][p];
        }
        cnt[k] = cnt[pre] + 1;
    }
    int query(int x, int y, int val, int len) {
        int res = 0;
        for (int i = len; ~i; i --) {
            int p = (val >> i) & 1;
            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]; }
            else x = ch[x][p], y = ch[y][p];
        }
        return res;
    }
} trie;
int root[N], sumxor[N];
char opt[5];
int n, m;
int main() {
    read(n); read(m);
    trie.ins(root[0], root[0], 0, 31);
    for (int i = 1; i <= n; i ++) {
        int x; read(x);
        sumxor[i] = sumxor[i - 1] ^ x;
        trie.ins(root[i], root[i - 1], sumxor[i], 31);
    }
    for (int i = 1; i <= m; i ++) {
        scanf("%s", opt); int x, l, r;
        if (opt[0] == 'A') {
            read(x); ++ n; sumxor[n] = sumxor[n - 1] ^ x;
            trie.ins(root[n], root[n - 1], sumxor[n], 31);
        }
        else {
            read(l); read(r); read(x); l --; r --;
            printf("%d\n", trie.query(root[l - 1], root[r], x ^ sumxor[n], 31));
        }
    }
    return 0;
}

⌈洛谷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. Python之加密模块

    hashlib模块 加密方式以md5方式加密举例 是标准模块,直接导入即可 还有其他的加密方式,比如:.sha1()..sha224()..sha256()等,加密后的字符串长度更长,安全性更高 一. ...

  2. MySQL 通过多个示例学习索引

    最近在准备面试,关于索引这一块,发现很多以前忽略的点,这里好好整理一下 首先为什么要建立索引 一本书,有章.节.段.行这种单位. 如果现在需要找一个内容:第9章>第2节>第3段>第4 ...

  3. 【转】linux下查看磁盘分区的文件系统格式

    https://www.cnblogs.com/youbiyoufang/p/7607174.html

  4. sql学习内容记录

    1.left函数 left(字段,长度):获取指定字段左侧的数据,类似substring函数 2.union / union all 将多个记录合并成一个完整的数据集 3.insert into se ...

  5. 【转帖】Linux定时任务Crontab命令详解

    Linux定时任务Crontab命令详解 https://www.cnblogs.com/intval/p/5763929.html 知道有crontab 以及 at 命令 改天仔细学习一下 讲sys ...

  6. PostgreSQL 安装了contrib 之后 登录失败的问题

    1. 自己之前只是安装了 pg 10.6 2. 开发同事 需要用到 一个extensions 叫做 uuid-ossp 3. 执行报错  详情见昨天的blog 4. 然后执行了升级操作 结果 pg10 ...

  7. 在linux和本地系统之间进行数据传输的简单方法--lrzsz

    lrzsz是一款在linux里可代替ftp上传和下载的程序. >>提君博客原创  http://www.cnblogs.com/tijun/  << 提君博客原创 安装和使用非 ...

  8. css3 text-shadow字体阴影讲解

    text-shadow:为字体添加阴影, 可以通过对text-shadow属性设置相关的属性值,来实现现一些需要的字体阴影效果,减少了图片的使用. 基础说明:    text-shadow: X轴  ...

  9. 转《JavaScript中的图片处理与合成》

    引言: 本系列现在构思成以下4个部分: 基础类型图片处理技术之缩放.裁剪与旋转(传送门): 基础类型图片处理技术之图片合成(传送门): 基础类型图片处理技术之文字合成(传送门): 算法类型图片处理技术 ...

  10. mapreduce join

    MapReduce Join 对两份数据data1和data2进行关键词连接是一个很通用的问题,如果数据量比较小,可以在内存中完成连接. 如果数据量比较大,在内存进行连接操会发生OOM.mapredu ...