散落星河的记忆🌠
Published on 2017-09-02 11:31 in 暂未分类 with 散落星河的记忆🌠

[十二省联考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;
}
posted @ 2019-04-08 19:50  散落星河的记忆🌠  阅读(142)  评论(0编辑  收藏  举报