WBLT 72pts 求助
查看原帖
WBLT 72pts 求助
366516
xuyiyang楼主2024/8/24 13:44

WA 13,15,20,23 MLE 19 码风良好的 WBLT 与 oi-wiki 的类似。求调 注意:代码中的 NN 开了 2.3×1062.3\times 10^6,包括垃圾回收

int n, m, v[N];

// WBLT
const double alpha = 0.25;
int q[N], hh = 0, tt = 0;
int w[N], ls[N], rs[N], idx;
int sz[N], id; 

void pushup(int x) { if (!ls[x] && !rs[x]) return ; sz[x] = sz[ls[x]] + sz[rs[x]]; w[x] = w[rs[x]]; }
int get(int v) {  
	if (hh != tt) { id = q[hh ++ ]; if (hh == N) hh = 0; }
	else id = ++ idx;
	w[id] = v, ls[id] = rs[id] = 0, sz[id] = 1;
	return id;
}
int build(int l, int r) {
	if (l == r) return get(v[l]);
	int mid = l + r >> 1, x = get(0);
	ls[x] = build(l, mid), rs[x] = build(mid + 1, r);
	return pushup(x), x;
}
int z;
int merge(int x, int y) {
	z = get(w[y]); ls[z] = x, rs[z] = y;
	return pushup(z), z;
}
void rotate(int x, int y) { // 0 left 1 right
	if (!y) {
		rs[x] = merge(rs[ls[x]], rs[x]);
		ls[x] = ls[ls[x]];
	} else {
		ls[x] = merge(ls[x], ls[rs[x]]);
		rs[x] = rs[rs[x]];
	}
}
void maintain(int x) {
	if (!ls[x] && !rs[x]) return ;
	if (sz[ls[x]] > sz[rs[x]]) {
		if (sz[rs[x]] >= sz[x] * alpha) return ;
		if (sz[rs[ls[x]]] >= sz[ls[x]] * (1 - 2 * alpha) / (1 - alpha)) rotate(ls[x], 1);
		rotate(x, 0);
	} else {
		if (sz[ls[x]] >= sz[x] * alpha) return ;
		if (sz[ls[rs[x]]] >= sz[rs[x]] * (1 - 2 * alpha) / (1 - alpha)) rotate(rs[x], 0);
		rotate(x, 1); 
	}
}
void cpy(int x, int y) { ls[x] = ls[y], rs[x] = rs[y], sz[x] = sz[y], w[x] = w[y]; }
void ins(int v, int x) {
	if (!ls[x] && !rs[x]) {
		ls[x] = get(min(v, w[x])), rs[x] = get(max(v, w[x]));
		pushup(x); return maintain(x), void();
	}
	if (v <= w[ls[x]]) ins(v, ls[x]); else ins(v, rs[x]);
	pushup(x); maintain(x);
}
void del(int v, int x, int fa) {
	if (!ls[x] && !rs[x]) {
		if (ls[fa] == x) cpy(fa, rs[fa]); else cpy(fa, ls[fa]);
		q[tt ++ ] = x; ls[x] = rs[x] = w[x] = sz[x] = 0;
		if (tt == N) tt = 0;
		return ;
	}
	if (v <= w[ls[x]]) del(v, ls[x], x); else del(v, rs[x], x);	
	pushup(x); maintain(x);
}
int rk(int v, int x) {
	if (!ls[x] && !rs[x]) return 1;
	if (v <= w[ls[x]]) return rk(v, ls[x]);
	return sz[ls[x]] + rk(v, rs[x]);
}
int kth(int v, int x) {
	if (!ls[x] && !rs[x]) return w[x];
	if (v <= sz[ls[x]]) return kth(v, ls[x]);
	return kth(v - sz[ls[x]], rs[x]);
}

bool Med;
int main() {
	int res = 0, lst = 0;
	rd(n), rd(m);
	for (int i = 1; i <= n; i ++ ) rd(v[i]); sort(v + 1, v + 1 + n); build(1, n);
	while (m -- ) {
		int op, x; rd(op), rd(x); x ^= lst;
		if (op == 1) ins(x, 1);
		else if (op == 2) del(x, 1, 0);
		else if (op == 3) lst = rk(x, 1), res ^= lst;
		else if (op == 4) lst = kth(x, 1), res ^= lst;
		else if (op == 5) lst = kth(rk(x, 1) - 1, 1), res ^= lst;
		else lst = kth(rk(x + 1, 1), 1), res ^= lst;
	} printf("%d\n", res);
	return 0;
}
2024/8/24 13:44
加载中...