题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1588
思路:splay模板题,
Splay树B站教学视频:https://www.bilibili.com/video/av19879546?from=search&seid=9869088591715950269
Splat树详解:https://blog.csdn.net/a_comme_amour/article/details/79382104
#include<algorithm>
#include<string.h>
#include<stdio.h>
#define M 100005
using namespace std;
int n,x,root,tot;
int f[M],key[M],ch[M][2];
void new_node(int &root,int far,int k)
{
root=++tot;
f[root]=far;
key[root]=k;
ch[root][0]=ch[root][1]=0;
return ;
}
void rol(int r,int kind)
{
int far=f[r],ffar=f[f[r]];
ch[far][!kind]=ch[r][kind];
f[ch[r][kind]]=far;
if(ffar) ch[ffar][ch[ffar][1]==far]=r;
f[r]=ffar;
ch[r][kind]=far;
f[far]=r;
return ;
}
void splay(int r,int goal)
{
while(f[r]!=goal)
{
if(f[f[r]]==goal) rol(r,ch[f[r]][0]==r);
else
{
int far=f[r],ffar=f[f[r]];
int kind=ch[ffar][0]==far;
if(ch[far][kind]==r)
{
rol(r,!kind);
rol(r,kind);
}
else
{
rol(far,kind);
rol(r,kind);
}
}
}
root=r;
return ;
}
int Insert(int k)
{
int r=root;
if(key[root]==k) return 0;
while(ch[r][key[r]<k])
{
r=ch[r][key[r]<k];
if(key[r]==k)
{
splay(r,0);
return 0;
}
}
new_node(ch[r][key[r]<k],r,k);
splay(ch[r][key[r]<k],0);
return 1;
}
int getl(int r)
{
int tem=ch[r][0];
if(tem==0)
return 0x3f3f3f3f;
while(ch[tem][1]) tem=ch[tem][1];
return key[r]-key[tem];
}
int getr(int r)
{
int tem=ch[r][1];
if(tem==0)
return 0x3f3f3f3f;
while(ch[tem][0]) tem=ch[tem][0];
return key[tem]-key[r];
}
int main()
{
scanf("%d",&n);
root=tot=0;
int ans=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&x);
if(i==1)
{
ans+=x;
new_node(root,0,x);
continue;
}
if(Insert(x)==0)continue;
ans+=min(getl(root),getr(root));
}
printf("%d\n",ans);
}