这道题呢就是一道经典的平衡树板题。
这道题的过程就是插入一个数旋转至根节点,然后查询根节点的前驱后继与它本身做差取最小即可。
参考代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define SG string
using namespace std;
const int Max=4e4+5;
const int Mod=1e9+7;
const int Inf=1e9;
int N,Ans,Cnt=1,Root,Fa[Max],Key[Max],Size[Max],CH[Max][2];
inline int Read(){
int X=0;char CH=getchar();bool F=0;
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
return F?-X:X;
}
inline void Write(int X){
if(X<0)X=-X,putchar('-');
if(X>9)Write(X/10);
putchar(X%10+48);
}
void Set(int X,int _Key,int _Size,int _Fa){
Key[X]=_Key;
Size[X]=_Size;
Fa[X]=_Fa;CH[X][0]=CH[X][1]=0;
}
void PushUp(int X){
Size[X]=Size[CH[X][0]]+Size[CH[X][1]]+1;
}
void Rotate(int X,int P){
int Y=Fa[X];
CH[Y][!P]=CH[X][P];
Fa[CH[X][P]]=Y;Fa[X]=Fa[Y];
if(Fa[X]){
CH[Fa[X]][CH[Fa[X]][1]==Y]=X;
}CH[X][P]=Y;Fa[Y]=X;
PushUp(Y);PushUp(X);
}
void Splay(int X,int To){
while(Fa[X]!=To){
if(Fa[Fa[X]]==To){
Rotate(X,CH[Fa[X]][0]==X);
} else {
int Y=Fa[X],Z=Fa[Y];
int P=(CH[Z][0]==Y);
if(CH[Y][P]==X){
Rotate(X,!P),Rotate(X,P);
} else {
Rotate(Y,P),Rotate(X,P);
}
}
}
if(To==0){
Root=X;
}
}
void Insert(int _Key){
if(!Root){
Set(Root=Cnt++,_Key,1,0);
} else {
int X=Root,Y=0;
while(X){
Y=X;X=CH[X][_Key>Key[X]];
}
Set(X=Cnt++,_Key,1,Y);
CH[Y][_Key>Key[Y]]=X;Splay(X,0);
}
}
int Pre(){
int X=CH[Root][0];
if(!X){
return Inf;
}
while(CH[X][1]){
X=CH[X][1];
}
return Key[X];
}
int Suc(){
int X=CH[Root][1];
if(!X){
return Inf;
}
while(CH[X][0]){
X=CH[X][0];
}
return Key[X];
}
int main(){
int I,J,K;
N=Read();
for(I=1;I<=N;I++){
K=Read();Insert(K);
int PRE=Pre();
int SUC=Suc();
if(I==1){
Ans=K;
} else {
Ans+=min(abs(K-PRE),abs(K-SUC));
}
}Write(Ans);
return 0;
}