其他分享
首页 > 其他分享> > 专题:可持久化数据结构

专题:可持久化数据结构

作者:互联网

目录

最大异或和

题意:
给定一个非负整数序列 a,初始长度为 N。
有 M 个操作,有以下两种操作类型:
A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N 增大 1。
Q l r x:询问操作,你需要找到一个位置 p,满足 l≤p≤r,使得:a[p] xor a[p+1] xor … xor a[N] xor x 最大,输出这个最大值。
题解:转化为求区间[l-1,r-1]内的s[i]和(s[n]^x)进行异或的最大值
构建可持久化01Trie
如果区间是[1,n],直接在普通的trie上贪心选择即可
如果没有区间左端点的限制,只需要在第r-1个版本的trie上贪心选择即可
对于限制[l-1,r-1],可以记录每个结点的两个子结点中较晚出现的版本号max_id,只需要在第r-1个版本的trie上贪心时保证走向结点的max_id>=l-1即可。
max_id可以在递归insert时自下而上求出来。

//
// Created by vv123 on 2022/9/9.
//
#include <bits/stdc++.h>
using namespace std;

const int N = 6e5 + 10, M = N * 25;

int n, m, s[N];
int tr[M][2], max_id[M], root[N], idx;

void insert(int i, int k, int pre, int now) {
    if (k < 0) {
        max_id[now] = i;
        return;
    }
    int v = s[i] >> k & 1;
    if (pre) tr[now][v ^ 1] = tr[pre][v ^ 1];
    tr[now][v] = ++idx;
    insert(i, k - 1, tr[pre][v], tr[now][v]);
    max_id[now] = max(max_id[tr[now][0]], max_id[tr[now][1]]);
}

int query(int root, int C, int L) {
    int p = root;
    for (int i = 23; i >= 0; i--) {
        int v = C >> i & 1;
        if (max_id[tr[p][v ^ 1]] >= L) p = tr[p][v ^ 1];
        else p = tr[p][v];
    }
    return C ^ s[max_id[p]];
}

int main() {
    cin >> n >> m;
    max_id[0] = -1;
    root[0] = ++idx;
    insert(0, 23, 0, root[0]);
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        s[i] = s[i - 1] ^ x;
        root[i] = ++idx;
        insert(i, 23, root[i - 1], root[i]);
    }
    while (m--) {
        string op; int l, r, x;
        cin >> op;
        if (op == "A") {
            cin >> x;
            n++;
            s[n] = s[n - 1] ^ x;
            root[n] = ++idx;
            insert(n, 23, root[n - 1], root[n]);
        } else {
            cin >> l >> r >> x;
            cout << query(root[r - 1], s[n] ^ x, l - 1) << "\n";
        }
    }
    return 0;
}

未完待续

标签:now,专题,持久,int,max,tr,数据结构,root,id
来源: https://www.cnblogs.com/vv123/p/16673619.html