题目链接

【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. 辨析element.offsetXxxx和element.style.xxxx

    DOM操作时,经常使用element.style属性,没错,element.style是属性,和几个offsetXxxx属性一样,概念是一样的. 但是style有几个属性,这几个属性和offsetXx ...

  2. Golang的类型断言

    类型断言即判断一个变量是不是某个类型的实例,这个经常用在判断接口的类型,基本的格式: y, ok := x.(type) 上面的语句用于判断变量x是不是type类型,有两种结果: x是type类型的变 ...

  3. 如何在 Linux 中查找最大的 10 个文件

    https://linux.cn/article-9495-1.html

  4. asp.net mvc导出execl_转载

    public FileResult ExportExcel() { var sbHtml = new StringBuilder(); sbHtml.Append("<table bo ...

  5. JS 验证输入框输入 只允许输入正实数(正整数,正小数),其他情况下不能输入 oninput事件

    input标签的oninput事件 要求输入框只输入正实数,包括整数和小数. 具体要求:整数部分不超过7位,可以没有小数,若有位数不超过2位. <input type="text&qu ...

  6. 区分Python中的可变对象和不可变对象

    参考: https://www.cnblogs.com/sun-haiyu/p/7096918.html """不过注意函数传参既不是传值也不是传引用,正确的叫法是传对象 ...

  7. python raise

    当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常.一旦执行了raise语句,raise后面的语句将不能执行.   演示raise用法 try: s = None if s ...

  8. Partition算法以及其应用详解下(Golang实现)

    接前文,除了广泛使用在快速排序中.Partition算法还可以很容易的实现在无序序列中使用O(n)的时间复杂度查找kth(第k大(小)的数). 同样根据二分的思想,每完成一次Partition我们可以 ...

  9. react事件绑定,事件传参,input单向数据绑定

    import React, { Component } from 'react'; class New extends Component { constructor(props){ super(pr ...

  10. Power Spectral Density

    对于一个特定的信号来说,有时域与频域两个表达形式,时域表现的是信号随时间的变化,频域表现的是信号在不同频率上的分量.在信号处理中,通常会对信号进行傅里叶变换得到该信号的频域表示,从而得到信号在频域上的 ...