题意:每输入一个数,找出最接近它的一个数。
这题是比较裸的平衡树的题,可以用STL轻松解决,但是刚学了平衡树Treap,所以就练习下平衡树。
第一次写平衡树,代码从LRJ的白书上和网上拼拼凑凑写出来了,感觉还挺好,真是名不虚传,平衡树太强大了。
以前一直觉得平衡树有多难多复杂,多次尝试使劲学之后才发现,其实没有那么复杂-。- 代码封装得不够好,以后慢慢修改吧!
#include <cstdio>
#include <cmath>
#include <climits>
#include <time.h>
#include <algorithm>
using namespace std;
struct Node {
Node *ch[2];
int p, v;
bool operator < (const Node rhs) const {
return p < rhs.p;
}
Node() {}
Node(int _v) {
ch[0] = ch[1] = NULL, p = rand(), v = _v;
}
};
struct Treap {
void rotate(Node* &o, int d) {
Node *z = o->ch[d ^ 1]; o->ch[d ^ 1] = z->ch[d];
z->ch[d] = o; o = z;
}
void insert(Node* &o, int x) {
if(o == NULL) {
o = new Node(x);
} else {
int d = x < o->v ? 0 : 1;
insert(o->ch[d], x);
if(o < o->ch[d])
rotate(o, d ^ 1);
}
}
void upper_bound(Node *o, int x, int &ans) {
if(o == NULL) return ;
if(o->v >= x) {
ans = o->v;
upper_bound(o->ch[0], x, ans);
} else {
upper_bound(o->ch[1], x, ans);
}
}
void lower_bound(Node *o, int x, int &ans) {
if(o == NULL) return ;
if(o->v <= x) {
ans = o->v;
lower_bound(o->ch[1], x, ans);
} else {
lower_bound(o->ch[0], x, ans);
}
}
} tree;
int main() {
int n, a, ans = 0, x, y;
scanf("%d%d", &n, &a);
Node *root = new Node(a);
tree.insert(root, a), ans += a;
for(int i = 1; i < n; i++) {
if(scanf("%d",&a) == EOF)
a = 0;
tree.lower_bound(root, a, x);
tree.upper_bound(root, a, y);
ans += min(abs(a - x), abs(a - y));
tree.insert(root, a);
}
printf("%d\n", ans);
return 0;
}