BZOJ 1588 Splay 入门

1 篇文章 0 订阅

首先= =Splay 的学习资料 

http://www.notonlysuccess.com/index.php/splay-tree/



平衡树的一个题

http://www.lydsy.com:808/JudgeOnline/problem.php?id=1588

插入 N 个数, 每次求其和其相差最小的数是几,然后输出绝对值的和。

这个题是有问题的。。。。这个OJ上的数据不完整

if(scanf("%d", &t) == EOF)
t = 0;

读到最后要加上这么一句,真吭啊。我以为又是自己哪里写挂了。


#include<stdio.h>
#include<algorithm>
using namespace std;
#define MAX 111111
#define INF 0x3f3f3f3f
#define FINF -0x3f3f3f3f
#define keyTree (ch[ch[root][1]][0])

struct SplayTree
{
	int ch[MAX][2];
	int pre[MAX];
	int val[MAX];
	//int sz[MAX];
	int root, top1;
	void NewNode(int &x, int c, int f)
	{
		x = ++top1;
		ch[x][0] = ch[x][1] = 0;
		val[x] = c;
		pre[x] = f;
	}
	
	int insert(int c)
	{
		int x = root;
		int f;
		while(ch[x][ c > val[x] ])
			x = ch[x][ c > val[x] ];
		NewNode(ch[x][ c > val[x] ], c, x);

		Splay(ch[x][ c > val[x] ], 0);
		
		return getAnswer(c);
	}
	
	int getAnswer(int c)
	{
		int l = ch[root][0];
		int r = ch[root][1];
		
		while(ch[l][1] != 0)
			l = ch[l][1];
		int nl = val[l];

		while(ch[r][0] != 0)
			r = ch[r][0];
		
		int nr = val[r];

		//printf(" nl : %d  nr : %d \n", nl, nr);
		return min(abs(c - nl), abs(nr - c));
	}
	
	void Rotate(int x, int f)
	{
		int y = pre[x];
		ch[y][!f] = ch[x][f];
		pre[ch[x][f]] = y;
		if(pre[y]) ch[pre[y]][ ch[pre[y]][1] == y ] = x;
		pre[x] = pre[y];
		ch[x][f] = y;
		pre[y] = x;
	}

	void Splay(int x, int goal)
	{
		while(pre[x] != goal)
		{
			if(pre[pre[x]] == goal)
				Rotate(x, ch[pre[x]][0] == x);
			else
			{
				int y = pre[x];
				int z = pre[y];
				int f = (ch[z][0] == y);
				if(ch[y][f] == x)
					Rotate(x, !f), Rotate(x, f);
				else
					Rotate(y, f), Rotate(x, f);
			}
		}
		if(goal == 0)
			root = x;
	}
	
	void debug()
	{
		printf("Root %d\n", root);
		travel(root);
	}
	
	void travel(int x)
	{
		printf("node : %d l : %d r : %d val : %d pre : %d \n", x, ch[x][0], ch[x][1], val[x], pre[x]);
		if(ch[x][0])
			travel(ch[x][0]);
		if(ch[x][1])
			travel(ch[x][1]);
	}
	
	void init()
	{
		val[0] = INF;
		root = top1 = 0;
		NewNode(root, FINF, 0);
		NewNode(ch[root][1], INF, root);
		//pre[ch[root][1]] = root;
	}
	
}sp;


int main()
{
	int n;
	sp.init();
	n = 0;
	scanf("%d", &n);
	
	int sum = 0;
	for(int i = 0; i < n; i++)
	{
		int t;
		if(scanf("%d", &t) == EOF)
			t = 0;
		if(i == 0)
		{
			sp.insert(t);
		//	sp.debug();
			sum += t;
			continue;
		}
		sum += sp.insert(t);
	//	sp.debug();
	}
	printf("%d\n", sum);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值