BZOJ 1588 朴素TREAP,寻找前驱和后继

不得不吐槽比较坑的数据。。

寻找前驱和后继,取差值较小即可

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <map>
#define LL int 
#define inf 2000000000;
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS
using namespace std;

struct node
{
	node *l, *r;
	int key, aux, cnt;
};
typedef node *Tnode;
Tnode root, nill;

inline void Build(){
	nill = new(node);
	nill->key = 0;
	nill->aux = inf;
	nill->cnt = 0;
	nill->l = nill->r = nill;
	root = nill;
}

inline void LeftRotate(Tnode &o){
	Tnode t = o->l;
	o->l = t->r;
	t->r = o;
	o = t;
}

inline void RightRotate(Tnode &o){
	Tnode t = o->r;
	o->r = t->l;
	t->l = o;
	o = t;
}

void Insert(Tnode &o, int key){
	if (o == nill){
		o = new(node);
		o->aux = ((rand() << 15) + rand()) % inf;
		o->key = key;
		o->l = o->r = nill;
		o->cnt = 1;
		return;
	}
	else if (o->key == key) o->cnt++;
	else{
		if (key < o->key) {
			Insert(o->l, key);
			if (o->l->aux < o->aux) LeftRotate(o);
		}
		else{
			Insert(o->r, key);
			if (o->r->aux < o->aux) RightRotate(o);
		}
	}
}

inline int FindPre(Tnode &o, int key){
	if (o == nill) return -int(1e9);
	if (key < o->key) return FindPre(o->l, key);
	else if (key == o->key) return key;
	else return max(o->key, FindPre(o->r, key));
}

inline int FindNext(Tnode &o, int key){
	if (o == nill) return int(1e9);
	if (key < o->key) return min(o->key, FindNext(o->l, key));
	else if (key == o->key) return key;
	else return  FindNext(o->r, key);
}

int n;

int main(){
	#ifdef ACM
	freopen("input.txt", "r", stdin);
	#endif
	while (scanf("%d", &n) != EOF){
		LL ans = 0;
		Build();
		for (int i = 0; i < n; i++){
			LL x; scanf("%d", &x);
		//	printf("i:%d  x:%d\n", i, x);
			printf("i:%d  x:%d\n", i, x);
			if (scanf("%d", &x) == EOF) x = 0;
			printf("i:%d  x:%d\n", i, x);
			int tmp = ans;
			if (i == 0) ans += x;
			else{
				int pre = FindPre(root, x);
				int next = FindNext(root, x);
			//	printf("i:%d  pre:%d  next:%d\n", i, pre, next);
				if (pre == (int)1e9 && next == -int(1e9)) continue;
				else if (pre == -int(1e9)) ans += next - x;
				else if(next == int(1e9)) ans += x - pre;
				else ans += min(next - x, x - pre);
			}
		//	printf("add:%d\n", ans - tmp);
			Insert(root, x);
		}
		printf("%d\n", ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值