解题方法:
每次找 min(大于a的最小值, 小于a 的最大值)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
using namespace std ;
const int maxn=500010 ;
const int inf=0x3f3f3f3f ;
struct SplayTree
{
int rt,id;
int son[maxn][2 ],val[maxn],pre[maxn];
void Rotate(int x,int c)
{
int y=pre[x];
son[y][!c]=son[x][c];
pre[son[x][c]]=y;
pre[x]=pre[y];
if (pre[y]) son[pre[y]][son[pre[y]][1 ]==y]=x;
son[x][c]=y;
pre[y]=x;
}
void Splay(int x,int goal)
{
while (pre[x]!=goal)
{
if (pre[pre[x]]==goal)
{
if (son[pre[x]][1 ]==x)
Rotate(x,0 );
else
Rotate(x,1 );
}
else {
int y=pre[x];
int z=pre[y];
if (son[z][0 ]==y){
if (son[y][0 ]==x){
Rotate(y,1 ),Rotate(x,1 );
}
else {
Rotate(x,0 ),Rotate(x,1 );
}
}
else {
if (son[y][1 ]==x){
Rotate(y,0 ),Rotate(x,0 );
}
else {
Rotate(x,1 ),Rotate(x,0 );
}
}
}
}
if (goal==0 ) rt=x;
}
void Newnode(int f,int &x,int a)
{
x=++id;
pre[x]=f;
val[x]=a;
son[x][0 ]=0 ,son[x][1 ]=0 ;
}
void Init()
{
id=0 ;
Newnode(0 ,rt,-inf);
Newnode(rt,son[rt][1 ],inf);
}
void Insert(int a)
{
int x=rt;
while (son[x][val[x]<a]) x=son[x][val[x]<a];
Newnode(x,son[x][val[x]<a],a);
Splay(id,0 );
}
int fx_min(int a)
{
int x=rt;
int Min=inf;
while (x){
if (val[x]==a) return a;
if (val[x]>a) Min=min(Min,val[x]);
if (val[x]>a) x=son[x][0 ];
else
x=son[x][1 ];
}
return Min;
}
int fx_max(int a)
{
int x=rt;
int Max=-inf;
while (x){
if (val[x]==a) return a;
if (val[x]<a) Max=max(Max,val[x]);
if (val[x]<a)
x=son[x][1 ];
else
x=son[x][0 ];
}
return Max;
}
}spy;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt" ,"r" ,stdin);
freopen("out.txt" ,"w" ,stdout);
#endif
int n,a,ans;
scanf ("%d%d" ,&n,&a);
spy.Init();
spy.Insert(a);
ans=a;
while (--n)
{
if (scanf ("%d" ,&a)==EOF) a=0 ;
ans+=min(fabs (a-spy.fx_min(a)),fabs (a-spy.fx_max(a)));
spy.Insert(a);
}
printf ("%d\n" ,ans);
return 0 ;
}