求助卡空间
查看原帖
求助卡空间
605226
modfisher楼主2023/12/16 13:49
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e6 + 5;

int lc[maxn * 30], rc[maxn * 30], sum[maxn * 30];
int tot = 0, ver[maxn], ltov[maxn], vtol[maxn], pre[maxn];

void up(int x){
	sum[x] = sum[lc[x]] + sum[rc[x]];
}
int build(int l, int r){
	int x = ++ tot;
	if(l == r) return x;
	int mid = l + r >> 1;
	lc[x] = build(l, mid);
	rc[x] = build(mid + 1, r);
	return x;
}
int clone(int x){
	tot ++;
	sum[tot] = sum[x], lc[tot] = lc[x], rc[tot] = rc[x];
	return tot;
}
int update(int x, int l, int r, int id){
	x = clone(x);
	if(l == id && r == id){
		sum[x] = 1;
		return x;
	}
	int mid = l + r >> 1;
	if(id <= mid) lc[x] = update(lc[x], l, mid, id);
	else rc[x] = update(rc[x], mid + 1, r, id);
	up(x);
	return x;
}
int query(int x){
	return sum[x];
}

int main(){
	int q;
	scanf("%d", &q);
	int maxv = 1000000;
	ver[0] = build(1, maxv);
	int len = 0, b = 0, now = 0;
	for(int i = 1; i <= q; i ++){
		string op;
		cin >> op;
		if(op == "+"){
			int a;
			scanf("%d", &a);
			b ++;
			pre[b] = now;
			now = b;
			ver[b] = update(ver[b - 1], 1, maxv, a);
			len ++;
		}else if(op == "-"){
			int k;
			scanf("%d", &k);
			b ++;
			pre[b] = now;
			now = b;
			ver[b] = ver[ltov[len - k]];
			len -= k;
		}else if(op == "!"){
			ver[b] = ver[now - 1];
			now = pre[now];
			len = vtol[b - 1];
		}else{
			printf("%d\n", query(ver[b]));
		}
		ltov[len] = b;
		vtol[b] = len;
	}
	return 0;
}

交上去会MLE,有没有什么办法把主席树空间再弄小点?

2023/12/16 13:49
加载中...