BZOJ1588
http://www.lydsy.com/JudgeOnline/problem.php?id=1588
splay维护一下前驱后继
#include<cstdio>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
inline int min(int a,int b){
return a<b?a:b;
}
const int N=100011,inf=(1<<30);
int num1,num2;
int n,x,ans;
namespace Splay{
int sz,rt;
int to[N][2],fa[N],num[N];
inline void rotate(int x,int &k){
register int y=fa[x],z=fa[y],l,r;
l=(x==to[y][0]?0:1);r=l^1;
if(y==k)
k=x;
else
to[z][0]==y?to[z][0]=x:to[z][1]=y;
fa[x]=z;fa[y]=x;fa[to[x][r]]=y;
to[y][l]=to[x][r];to[x][r]=y;
}
inline void modify(int x,int &k){
register int y,z;
while(x!=k){
y=fa[x];z=fa[y];
if(y!=k)((to[y][0]==x)^(to[z][0]==y))?rotate(x,k):rotate(y,k);
rotate(x,k);
}
}
inline void insert(int &k,int x,int father=0){
if(!k){
k=++sz;
fa[k]=father;
num[k]=x;
modify(k,rt);
return ;
}
x<num[k]?insert(to[k][0],x,k):insert(to[k][1],x,k);
}
inline void ask_before(int k,int x){
if(!k)return;
if(num[k]<=x){
num1=num[k];
ask_before(to[k][1],x);
}
else
ask_before(to[k][0],x);
}
inline void ask_after(int k,int x){
if(!k)return;
if(num[k]>=x){
num2=num[k];
ask_after(to[k][0],x);
}
else
ask_after(to[k][1],x);
}
}
using namespace Splay;
int main(){
scanf("%d",&n);
FOR(i,1,n){
num1=-inf;num2=inf;
scanf("%d",&x);
ask_after(rt,x);
ask_before(rt,x);
ans+=(i!=1?min(num2-x,x-num1):x);
insert(rt,x);
}
printf("%d",ans);
return 0;
}