[十二省联考2019]异或粽子 (可持久化01tire 堆)

Posted luoyibujue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[十二省联考2019]异或粽子 (可持久化01tire 堆)相关的知识,希望对你有一定的参考价值。

/*
查询异或最大值的方法是前缀和一下, 在01trie上二分
那么我们可以对于n个位置每个地方先求出最大的数, 然后把n个信息扔到堆里, 当我们拿出某个位置的信息时, 将他去除当前最大后最大的信息插入到堆中
所以动态维护01trie就可以了 



*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#define mmp make_pair
#define ll long long
#define M 500010
using namespace std;
ll read() {
    ll nm = 0, f = 1;
    char c = getchar();
    for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for(; isdigit(c); c = getchar()) nm =nm * 10 + c - '0';
    return nm * f;
}
int rt[M], qy[M * 2],  sz[M * 86], lc[M * 86], rc[M * 86], n, k, cnt, tot, biao[M];
ll a[M], sum[M], ans;
priority_queue<pair<ll, int> > que;

void insert(int lst, int &now, ll x, int dep) {
    now = ++cnt;
    sz[now] = sz[lst] + 1;
    lc[now] = lc[lst], rc[now] = rc[lst];
    if(dep == -1) return;
    if(x & (1ll << dep)) insert(rc[lst], rc[now], x, dep - 1);
    else insert(lc[lst], lc[now], x, dep - 1);
}

ll work(int lst, int &now, ll x, int dep) {
    now = ++cnt;
    sz[now] = sz[lst] - 1;
    lc[now] = lc[lst], rc[now] = rc[lst];
    if(dep == -1) return 0;
    if(x & (1ll << dep)) 
    {
        if(sz[lc[now]]) return (1ll << dep) + work(lc[lst], lc[now], x, dep - 1);
        else return work(rc[lst], rc[now], x, dep - 1);
    }
    else
    {
        if(sz[rc[now]]) return (1ll << dep) + work(rc[lst], rc[now], x, dep - 1);
        else return work(lc[lst], lc[now], x, dep - 1);
    }
}

int main() {
    //freopen("xor2.in", "r", stdin);
//  freopen("xor.in", "r", stdin); freopen("xor.out", "w", stdout);
    n = read(), k = read();
    for(int i = 1; i <= n; i++) a[i] = read(), sum[i] = sum[i - 1] ^ a[i];
    for(int i = 1; i <= n; i++) {
        insert(rt[i - 1], rt[i], sum[i - 1], 33);
        ll now = work(rt[i], qy[i], sum[i], 33);
        biao[i] = i;
        que.push(mmp(now, i));
    }
    tot = n;
    for(int i = 1; i <= k; i++) {
        ans += que.top().first;
        int now = que.top().second;
        que.pop();
        int id = biao[now];
        if(sz[qy[id]]) {
            tot++;
            ll zz = work(qy[id], qy[tot], sum[now], 33);
            biao[now] = tot;
            que.push(mmp(zz, now));
        }
    }
    cout << ans << "
";
    return 0;
}

以上是关于[十二省联考2019]异或粽子 (可持久化01tire 堆)的主要内容,如果未能解决你的问题,请参考以下文章

[十二省联考2019]异或粽子(可持久化tire,堆)

P5283 [十二省联考2019]异或粽子 可持久化字典树

[十二省联考2019] 异或粽子 解题报告 (可持久化Trie+堆)

题解Luogu P5283 [十二省联考2019]异或粽子

P5283 [十二省联考2019]异或粽子

P5283 [十二省联考2019]异或粽子