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

跟超级钢琴做法差不多, 就是 [l,r] 中的最大值的位置是 k, 那么次大值的位置必定在 [l,k-1] 和 [k+1,r] 其中之一的思想。

#include <bits/stdc++.h>
typedef long long LL;
using namespace std;

const int N = 5e5, K = 2e5;

LL rd() {
	LL x = 0ll;
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x;
}

int n, k; // 1 << 31
LL A[N + 233];
struct Trie { int c[2], col; Trie() {c[0]=c[1]=col=0;} } a[N * 34 + 2333];
int tot, root[N + 233];

void init() {
	int p = root[0] = ++ tot;
	for (int i = 31; ~ i; -- i) a[p].c[0] = ++ tot, p = tot;
}

void ins (int id, LL x) {
	int p = root[id - 1], q = root[id] = ++ tot;
	a[q].col = id;
	for (int i = 31; ~ i; -- i) {
		int v = (x >> i) & 1;
		a[a[q].c[v] = ++ tot].col = id;
		a[q].c[v ^ 1] = a[p].c[v ^ 1];
		p = a[p].c[v], q = tot;
	}
}

pair<LL,int> ask (int l, int r, LL x) {
	LL res = 0ll;
	int p = root[r];
	for (int i = 31; ~ i; -- i) {
		int v = (x >> i) & 1;
		if (a[p].c[v ^ 1] && a[a[p].c[v ^ 1]].col >= l)
			res += (1ll << i), p = a[p].c[v ^ 1];
		else
			p = a[p].c[v];
	}
	return make_pair (res, a[p].col);
}

struct sta {	int l, r, x; LL v; int pos; sta (int a, int b, int c, LL d, int e) : l(a), r(b), x(c), v(d), pos(e) {} sta() {}
 } q[N*2+23];
bool operator < (sta s1, sta s2) { return s1.v < s2.v; }
int tp;


int main()
{
	init();
	n = rd(), k = rd();
	for (int i = 1; i <= n; ++ i) A[i] = A[i - 1] ^ rd(), ins (i, A[i]);
	for (int i = 1; i <= n; ++ i) {
		pair<LL,int> tmp = ask (0, i - 1, A[i]);
		q[++ tp] = sta (0, i - 1, i, tmp.first, tmp.second);
		push_heap (q + 1, q + 1 + tp);
	}
	LL ans = 0ll;
	for (int i = 1; i <= k; ++ i) {
		sta now = q[1];
		pop_heap (q + 1, q + 1 + tp);
		-- tp;
		ans += now.v;
		int x = now.x, l = now.l, r = now.r, k = now.pos;
		if (l < k) {
			pair<LL,int> tmp = ask (l, k - 1, A[x]);
			q[++ tp] = sta (l, k - 1, x, tmp.first, tmp.second);
			push_heap (q + 1, q + tp + 1);
		}
		if (k < r) {
			pair<LL,int> tmp = ask (k + 1, r, A[x]);
			q[++ tp] = sta (k + 1, r, x, tmp.first, tmp.second);
			push_heap (q + 1, q + tp + 1);
		}
	}
	cout << ans;
	return 0;
}
原文地址:https://www.cnblogs.com/tztqwq/p/14476667.html