题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1588
Splay模板题。。
#include <cstdio>
#include <iostream>
using namespace std;
#define Key_value (ch[root][ch[root][1]])
const int inf = 0x3f3f3f3f;
const int maxn = 1e6+10;
// splay
int tot1, root;
int pre[maxn], ch[maxn][2];
int key[maxn];
void newNode(int &r, int father, int k)
{
r = ++tot1;
pre[r] = father;
key[r] = k;
ch[r][0] = ch[r][1] = 0;
}
void init()
{
pre[0] = ch[0][0] = ch[0][1] = 0;
tot1 = root = 0;
}
void Rotate(int x, int kind)
{
int y = pre[x];
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y]) ch[pre[y]][y == ch[pre[y]][1]] = x;
pre[x] = pre[y];
pre[y] = x;
ch[x][kind] = y;
}
void Splay(int r, int goal)
{
while(pre[r] != goal)
{
if(pre[pre[r]] == goal) Rotate(r, r == ch[pre[r]][0]);
else
{
int y = pre[r];
int kind = (y == ch[pre[y]][0]);
if(r == ch[y][kind])
{
Rotate(r, !kind);
Rotate(r, kind);
}
else
{
Rotate(y, kind);
Rotate(r, kind);
}
}
}
if(goal == 0) root = r;
}
void Insert(int k)
{
int r = root;
while( ch[r][key[r] < k] )
{
r = ch[r][key[r]<k];
}
newNode(ch[r][key[r]<k], r, k);
Splay(ch[r][key[r]<k], 0);
}
// 前驱:左子树的最右端点
int get_pre(int x)
{
int r = ch[x][0];
if(r == 0) return inf;
while(ch[r][1]) r = ch[r][1];
return key[x] - key[r];
}
//后继:右子树的最左端点
int get_next(int x)
{
int r = ch[x][1];
if(r == 0) return inf;
while(ch[r][0]) r = ch[r][0];
return key[r] - key[x];
}
int main()
{
int t, ans = 0, n;
scanf("%d", &n);
for(int i=0;i<n;i++)
{
if( scanf("%d", &t) == EOF) t = 0; // 测试数据有问题。。
Insert(t);
if(i == 0)
{
ans = t;
newNode(root, 0, t);
}
else
{
int a = get_pre(root);
int b = get_next(root);
ans += min(a, b);
}
}
cout << ans << endl;
return 0;
}