题意:给一个数列,求std::set
就好,既然要练习Treap,便又手写了一棵平衡树。
// std::set 292ms
#include <cstdio>
#include <set>
#include <functional>
#include <algorithm>
using namespace std;
const int inf = (1LL<<31)-1;
int main()
{
int n, ans;
set<int> S;
set<int, greater<int> > T;
scanf("%d %d", &n, &ans);
--n;
S.insert(ans);
T.insert(ans);
while (n--) {
int x, d = inf;
scanf("%d", &x);
set<int>::iterator ix = S.lower_bound(x);
if (ix != S.end())
d = min(d, *ix - x);
set<int, greater<int> >::iterator iy = T.lower_bound(x);
if (iy != T.end())
d = min(d, x - *iy);
ans += d;
S.insert(x);
T.insert(x);
}
printf("%d\n", ans);
return 0;
}
{% raw %}
// Treap 208ms
#include <cstdio>
#include <algorithm>
#include <cstdlib>
typedef long long ll;
const int MAX_N = 1e5 + 1, inf = (1LL<<31)-1;
struct Node {
Node* ch[2];
int v, r;
} nodes[MAX_N], * null = nodes, * root = null;
namespace Treap {
Node* new_node(int v)
{
static Node* cur = nodes + 1;
*cur = (Node){{null, null}, v, rand()};
return cur++;
}
inline void rotate(Node* &x, int d)
{
Node* y = x->ch[d];
x->ch[d] = y->ch[d^1];
y->ch[d^1] = x;
x = y;
}
void insert(Node* &x, int v)
{
if (x == null)
x = new_node(v);
else if (x->v != v) {
int d = v > x->v;
insert(x->ch[d], v);
if (x->ch[d]->r > x->r)
rotate(x, d);
}
}
int pre(Node* x, int v)
{
Node* y = null;
while (x != null) {
if (x->v == v)
return v;
if (v < x->v)
x = x->ch[0];
else {
y = x;
x = x->ch[1];
}
}
return y == null ? -inf : y->v;
}
int suc(Node* x, int v)
{
Node* y = null;
while (x != null) {
if (x->v == v)
return v;
if (v > x->v)
x = x->ch[1];
else {
y = x;
x = x->ch[0];
}
}
return y == null ? inf : y->v;
}
}
int main()
{
using namespace Treap;
srand(65535);
int n, ans;
scanf("%d %d", &n, &ans);
insert(root, ans);
--n;
while (n--) {
int x;
scanf("%d", &x);
ans += std::min((ll)x - pre(root, x), suc(root, x) - (ll)x);
insert(root, x);
}
printf("%d\n", ans);
return 0;
}
{% endraw %}