[十二省联考2019] 异或粽子
Description
Solution
by 讲的很好还最可爱哒gxb
Code
#include <queue>
#include <cstdio>
const int N = 500005, M = 20000000;
typedef long long LL;
struct Pair {
LL x; int y, z;
bool operator < (const Pair & rhs) const {
return x < rhs.x;
}
};
LL a[N], ans;
int ch[M][2], sum[M], sz;
std::priority_queue<Pair> q;
LL read() {
LL x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x;
}
void insert(LL y) {
int x = 0;
for (int i = 31; ~i; --i) {
if ((y >> i) & 1) {
if (!ch[x][1]) ch[x][1] = ++sz;
x = ch[x][1], ++sum[x];
} else {
if (!ch[x][0]) ch[x][0] = ++sz;
x = ch[x][0], ++sum[x];
}
}
}
LL query(LL y, int k) {
int x = 0; LL z = 0;
for (int i = 31; ~i; --i) {
int c = (y >> i) & 1;
if (sum[ch[x][c ^ 1]] >= k) z = (z << 1) | 1, x = ch[x][c ^ 1];
else z = z << 1, k -= sum[ch[x][c ^ 1]], x = ch[x][c];
}
return z;
}
int main() {
int n = read(), k = read() << 1;
insert(0);
for (int i = 1; i <= n; ++i) a[i] = a[i - 1] ^ read(), insert(a[i]);
for (int i = 0; i <= n; ++i) q.push((Pair){query(a[i], 1), i, 1});
while (k--) {
Pair now = q.top();
ans += now.x, q.pop();
if (n < now.z + 1) continue;
q.push((Pair){query(a[now.y], now.z + 1), now.y, now.z + 1});
}
printf("%lld\n", ans >> 1);
return 0;
}