题面
输入样例
6
5
1
2
5
4
6
输出样例
12
题解
- 这道题的意思就是对于 ai ,在前i个数中找一个与ai差值最小的数,做法还是很多的,我们可以直接用set做,也可以用邻接表做,还可以用treap做,代码是treap的
- 这题就是用treap找一个前驱(这里不是严格小于,因为等于才是最优解,模板代码看具体),然后找一个后继(也不是严格大于),然后判断前驱和后继哪个和当前值的差值是最小的即可
- 因为还是平衡树的模板,这里就不解释了,看模板点这里
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int INF = 1e7;
int n, a;
int root, idx;
struct Node {
int l, r;
int key, val;
} tr[N];
int get_node(int key) {
tr[++idx].key = key;
tr[idx].val = rand();
return idx;
}
void zig(int &p) {
//右旋
int q = tr[p].l;
tr[p].l = tr[q].r, tr[q].r = p, p = q;
}
void zag(int &p) {
//左旋
int q = tr[p].r;
tr[p].r = tr[q].l, tr[q].l = p, p = q;
}
void build() {
get_node(-INF);
get_node(INF);
root = 1;
tr[1].r = 2;
if (tr[2].val > tr[1].val) zag(root);
}
void insert(int &p, int key) {
if (!p) p = get_node(key);
else if (tr[p].key == key) return;
else if (tr[p].key > key) {
insert(tr[p].l, key);
if (tr[tr[p].l].val > tr[p].val) zig(p);
} else {
insert(tr[p].r, key);
if (tr[tr[p].r].val > tr[p].val) zag(p);
}
}
int get_prev(int p, int key) {
//找前驱
if (!p) return -INF;
else if (tr[p].key == key) return tr[p].key;
if (tr[p].key >= key) return get_prev(tr[p].l, key);
else return max(tr[p].key, get_prev(tr[p].r, key));
}
int get_next(int p, int key) {
//找后继
if (!p) return INF;
else if (tr[p].key == key) return tr[p].key;
if (tr[p].key <= key) return get_next(tr[p].r, key);
else return min(tr[p].key, get_next(tr[p].l, key));
}
int main() {
build();
cin >> n;
ll res = 0;
for (int i = 1; i <= n; i++) {
cin >> a;
if (i == 1) {
res += a;
} else {
res += min(abs(a - get_prev(root, a)), abs(get_next(root, a) - a));
}
insert(root, a);
}
cout << res << endl;
return 0;
}