求助TLE49,写了个splay应该没问题的啊,为什么过不去
查看原帖
求助TLE49,写了个splay应该没问题的啊,为什么过不去
66548
onglu楼主2020/9/6 13:56

#include <bits/stdc++.h>
#define int long long
#define val(x) tree[x].val
#define fa(x) tree[x].fa
#define son(x, k) tree[x].ch[k]
#define sum(x) tree[x].sum
#define siz(x) tree[x].siz
#define ll long long
#define ull unsigned long long
#define FILL ""
using namespace std;
const int N = 5e6 + 1009;
const int inf = (1ll << 62) - 1;
int read(){
	char c; int num, f = 1;
	while(c = getchar(),!isdigit(c)) if(c == '-')f = -1; num = c - '0';
	while(c = getchar(), isdigit(c)) num = num * 10 + c - '0';
	return num * f;
}
struct Node{
	int val, fa, ch[2], siz, sum;
}tree[N];
int n, root, tot;
int chk(int x){
	return son(fa(x), 1) == x;
}
void update(int x){
	siz(x) = siz(son(x, 0)) + siz(son(x, 1)) + 1;
	sum(x) = sum(son(x, 0)) + sum(son(x, 1)) + val(x);
}
void rotate(int x){
	int y = fa(x), z = fa(y), k = chk(x), w = son(x, k ^ 1);
	son(y, k) = w; fa(w) = y;
	son(z, chk(y)) = x; fa(x) = z;
	son(x, k ^ 1) = y; fa(y) = x;
	update(y); update(x);
}
void splay(int x, int goal = 0){
	while(fa(x) != goal){
		int y = fa(x), z = fa(y);
		if(z != goal){
			if(chk(x) == chk(y))rotate(y);
			else rotate(x);
		}
		rotate(x);
	}
	if(!goal) root = x;
}
int New(int x, int pre){
	tot++;
	if(pre)son(pre, x > val(pre)) = tot;
	sum(tot) = val(tot) = x;
	son(tot, 0) = son(tot, 1) = 0;
	fa(tot) = pre; siz(tot) = 1;
	return tot;
}
void Insert(int x){
	int p = 0, cur = root;
	while(cur){
		p = cur;
		cur = son(cur, x > val(cur));
	}
	cur = New(x, p);
	splay(cur);
}
void Find(int x){
	if(!root)return ;
	int cur = root;
	while(val(cur) != x && son(cur, x > val(cur)))
		cur = son(cur, x > val(cur));
	splay(cur);
}
int Pre(int x){
	Find(x);
	if(val(root) < x)return root;
	int cur = son(root, 0);
	while(son(cur, 1))
		cur = son(cur, 1);
	return cur;
}
int Succ(int x){
	Find(x);
	if(val(root) > x)return root;
	int cur = son(root, 1);
	while(son(cur, 0))
		cur = son(cur, 0);
	return cur;
}
void Del(int x){
	int lst = Pre(x), nxt = Succ(x);
	splay(lst); splay(nxt, lst);
//	cout<<val(son(nxt, 0))<<endl;
	son(nxt, 0) = 0;
//	update(nxt); update(root);
	splay(nxt);
}
int getsum(int k){
	int cur = root, ans = 0;
	while(1){
//		cout<<cur<<endl;
		if(son(cur, 1) && siz(son(cur, 1)) >= k) cur = son(cur, 1);
		else if(siz(son(cur, 1)) + 1 == k)return ans + sum(son(cur, 1)) + val(cur);
		else ans += sum(son(cur, 1)) + val(cur), k -= siz(son(cur, 1)) + 1, cur = son(cur, 0);
	}
}
int getrank(int x){
	Find(x);
	return siz(son(root, 1));
}
int cntl, cnta;
set<int> S;
main()
{
	//freopen(FILL".in", "r", stdin);
	//freopen(FILL".out", "w", stdout);
	n = read();
	Insert(inf); Insert(-inf);
	for(int i = 1; i <= n; i++){
		int opt = read(), d = read();
		if(opt){
			if(d > 0)S.insert(d), cntl++;
			if(d < 0)S.erase(-d), cntl --;
		}
		if(d > 0)Insert(d), cnta++;
		else Del(-d), cnta--;
//		cout<<sum(root)<<endl;
		int minn = *S.begin();
		if(getrank(minn) <= cntl){
			if(cnta >= cntl + 1)
				printf("%lld\n", sum(root) + getsum(cntl + 2) - inf - minn);
			else printf("%lld\n", sum(root) + getsum(cntl + 1) - inf - minn);
		}else {
			printf("%lld\n", sum(root) + getsum(cntl + 1) - inf);
		}
	}
	return 0;
}
2020/9/6 13:56
加载中...