蒟蒻求助Treap
查看原帖
蒟蒻求助Treap
155826
明依楼主2020/4/27 16:02

第8个点WA了(比正确答案大1)

求大佬帮我康康吧qwq

#include <cstdio>
#include <cstdlib>

using namespace std;

#define ll long long
#define R register
#define U unsigned
#define qwq printf("qwq\n")
#define min(a, b) (a)<(b)?(a):(b)

const int N = 33000, INF = 1 << 30;

int n, tot, root, ans;

struct treap {
	int l, r;
	int val, dat;
	int cnt;
} a[N];

inline int New (int val) {
	a[++tot].val = val;
	a[tot].dat = rand();
	a[tot].cnt = 1;
	return tot;
}//新建节点 

inline void build () {
	New(-INF), New(INF);
	root = 1, a[1].r = 2;
}//初始化 

inline void zig (int &p) {
	int q = a[p].l;
	a[p].l = a[q].r;
	a[q].r = p;
	p = q;
}//右旋 

inline void zag (int &p) {
	int q = a[p].r;
	a[p].r = a[q].l;
	a[q].l = p;
	p = q;
}//左旋 

inline void insert (int &p, int val) {
	if (!p) {
		p = New(val);
		return;
	}
	if (val == a[p].val) a[p].cnt++;
	else if (val < a[p].val) {
		insert(a[p].l, val);
		if (a[p].dat < a[a[p].l].dat) zig(p);
	} else {
		insert(a[p].r, val);
		if (a[p].dat < a[a[p].r].dat) zag(p);
	}
}//插入节点 

inline int getpre (int val) {
	int ans = 1;
	int p = root;
	while (p) {
		if (val == a[p].val) {
			if (a[p].l) {
				p = a[p].l;
				while (a[p].r) p = a[p].r;
				ans = p;
			}
			break;
		}
		if (a[p].val < val && a[p].val > a[ans].val) ans = p;
		p = val<a[p].val?a[p].l:a[p].r;
	}
	return a[ans].val;
}//求前驱 

inline int getnext (int val) {
	int ans = 2;//a[2].val==INF
	int p = root;
	while (p) {
		if (val == a[p].val) {
			if (a[p].r) {
				p = a[p].r;
				while (a[p].l) p = a[p].l;
				ans = p;
			}
			break;
		}
		if (a[p].val > val && a[p].val < a[ans].val) ans = p;
		p = val<a[p].val?a[p].l:a[p].r;
	}
	return a[ans].val;
}//求后继 

inline bool find (int val) {
	int now = root;
	while (now) {
		if (val == a[now].val) break;
		else if (val < a[now].val) now = a[now].l;
		else now = a[now].r;
	}
	return a[now].cnt > 1;
}//判断Treap中是否存在多个Val 

int main () {
	scanf("%d", &n);
	build();
	for (int i = 1; i <= n; i++) {
		int x;
		scanf("%d", &x);
		insert(root, x);
		int pre = getpre(x), Next = getnext(x), k = find(x), z = INF;
		if (pre) z = min(z, abs(x - pre));//如果存在前缀就比较 
		if (Next) z = min(z, abs(x - Next));
		if (k) z = 0;//存在多个重复节点,最小值为0 
		if (i == 1) z = x;//特判i==1 
		ans += z;
	}
	printf("%d\n", ans);
	return 0;
}
2020/4/27 16:02
加载中...