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

貌似是个签到题?

白送的60分就不讲了,就是前缀和一下。
加上的40分可以用“序列合并”一题的套路,搞一个可持久化01trie维护xor第k大即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 500000 + 5;
int n, k, pre[N], a[N], root[N];

struct Node {
int r, xorans, nownum;
bool operator < (const Node &rhs) const {
return xorans < rhs.xorans;
}
};
struct Trie {
int trie[N*35][2], sz[N*35], pos = 0;
void pushup(int now) {
sz[now] = sz[trie[now][0]] + sz[trie[now][1]];
}
void Build(int& now, int x, int k) {
now = ++pos;
if(k == -1) {
sz[now]++;
return ;
}
if(!(x & (1ll << k))) Build(trie[now][0], x, k-1);
else Build(trie[now][1], x, k-1);
pushup(now);
}
void Update(int& now, int old, int x, int k) {
now = ++pos; trie[now][0] = trie[old][0], trie[now][1] = trie[old][1], sz[now] = sz[old];
if(k == -1) {
sz[now]++;
return ;
}
if(!(x & (1ll << k))) Update(trie[now][0], trie[old][0], x, k-1);
else Update(trie[now][1], trie[old][1], x, k-1);
pushup(now);
}
int XorKth(int now, int ans, int x, int k, int kth) {
if(k == -1) return ans;
if(!(x & (1ll << k))) {
int ls = sz[trie[now][0]], rs = sz[trie[now][1]];
if(kth <= ls) return XorKth(trie[now][0], ans * 2, x, k-1, kth);
else return XorKth(trie[now][1], ans * 2 + 1, x, k-1, kth - ls);
} else {
int ls = sz[trie[now][1]], rs = sz[trie[now][0]];
if(kth <= ls) return XorKth(trie[now][1], ans * 2 + 1, x, k-1, kth);
else return XorKth(trie[now][0], ans * 2, x, k-1, kth - ls);
}
}
}t;

signed main() {
scanf("%lld%lld", &n, &k);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]), pre[i] = (pre[i-1] ^ a[i]);
t.Build(root[1], pre[0], 32);
for(int i = 2; i <= n; i++)
t.Update(root[i], root[i-1], pre[i-1], 32);

priority_queue <Node> q;
for(int i = 1; i <= n; i++) {
int xo = t.XorKth(root[i], 0, pre[i], 32, i);
q.push((Node){i, (xo ^ pre[i]), i});
}

int ans= 0;
for(int i = 1; i <= k; i++) {
Node x = q.top(); q.pop();
//cout << x.xorans << endl;
ans += x.xorans;
if(i == k) {
cout<<ans << endl;
return 0;
}
else {
int id = x.nownum;
--id;
if(id <= 0) continue;
int xo = t.XorKth(root[x.r], 0, pre[x.r], 32, id);
q.push((Node){x.r, (xo ^ pre[x.r]), id});
}
}
cout <<ans << endl;
return 0;
}

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×