码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-04-07 22:07:32      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:insert   +=   pen   ios   持久化   cst   trie   space   else   

/*
查询异或最大值的方法是前缀和一下, 在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 << "\n";
    return 0;
}

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

标签:insert   +=   pen   ios   持久化   cst   trie   space   else   

原文地址:https://www.cnblogs.com/luoyibujue/p/10667216.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!