HYSBZ 1588 营业额统计(splay)

换一下splay的写法。。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define mxn 100020
#define inf 0x3f3f3f3f

int pre[mxn], ch[mxn][2], key[mxn], tot;
int root;

int creat(int fa, int val) {
	int ret = ++tot;
	pre[ret] = fa;
	key[ret] = val;
	ch[ret][0] = ch[ret][1] = 0;
	return ret;
}
void rt(int x, int d) {
	int y = pre[x];
	ch[y][d^1] = ch[x][d];
	pre[ch[x][d]] = y;
	if(pre[y]) 
		ch[pre[y]][ch[pre[y]][1]==y] = x;
	pre[x] = pre[y];
	ch[x][d] = y;
	pre[y] = x;
}
void splay(int x, int goal) {
	while(pre[x] != goal) {
		if(pre[pre[x]] == goal) {
			rt(x, ch[pre[x]][0] == x);
		}
		else {
			int y = pre[x];
			int d = ch[pre[y]][0] == y;
			if(ch[y][d] == x) {
				rt(x, !d);
				rt(x, d);
			}
			else {
				rt(y, d);
				rt(x, d);
			}
		}
	}
	if(goal == 0) root = x;
}

bool insert(int k) {
	if(root == 0) {
		root = creat(0, k);
		return 1;
	}
	int x = root;
	while(ch[x][key[x]<k]) {
		if(key[x] == k) {
			splay(x, 0);
			return 0;
		}
		x = ch[x][key[x]<k];
	}
	if(key[x] == k) {
		splay(x, 0);
		return 0;
	}
	ch[x][key[x]<k] = creat(x, k);
	splay(ch[x][key[x]<k], 0);
	return 1;
}
int getPre(int x) {
	int t = ch[x][0];
	if(t == 0) return inf;
	while(ch[t][1]) t = ch[t][1];
	return key[x] - key[t];
}
int getNext(int x) {
	int t = ch[x][1];
	if(t == 0) return inf;
	while(ch[t][0]) t = ch[t][0];
	return key[t] - key[x];
}
void debug() {
	for(int i = 1; i <= tot; ++i) {
		printf("node[%d], ch %d %d, pre %d\n", i, ch[i][0], ch[i][1], pre[i]);
	}
}
int main() {
	int n;
	while(scanf("%d", &n) != EOF) {
		root = tot = 0;
		int ans = 0;
		for(int i = 1; i <= n; ++i) {
		//	debug();
			int x;
			if(scanf("%d", &x) == EOF) x = 0;
			if(i == 1) {
				insert(x);
				ans = x;
				continue;
			}
			if(!insert(x)) continue;
			int t = min(getPre(root), getNext(root));
			ans += t;
		}
		printf("%d\n", ans);
	}
	return 0;
}


你可能感兴趣的:(HYSBZ 1588 营业额统计(splay))