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; }