https://loj.ac/problem/10143
题目描述
给出一个(n)个数的数列,定义(f_i=min{|a_i-a_j|}(ige j)),求(sum f_i)
思路
题目就要我们求在这个数之前并且和这个数的差最小的数,我们考虑这个数必定出现在当前(a_i)的前驱或后继中。所以我们可以用平衡树维护这个数列,每次求一下前驱和后继,注意这里可以相等,再把原数插入进去即可。
代码
#include<bits/stdc++.h>
using namespace std;
int read()
{
int res=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res*w;
}
const int INF=0x3f3f3f3f;
const int N=1e6+10;
#define root t[0].son[1]
struct Splay
{
struct Node
{
int val,siz,son[2],fa,cnt;
void init(int x,int f)
{
son[0]=son[1];
siz=cnt=1;
val=x;fa=f;
}
}t[N];
int tot;
int ident(int x){return t[t[x].fa].son[0]==x?0:1;}
void change(int x,int f,int o){t[x].fa=f;t[f].son[o]=x;}
void pushup(int x){t[x].siz=t[t[x].son[0]].siz+t[t[x].son[1]].siz+t[x].cnt;}
void rotate(int x)
{
int y=t[x].fa,z=t[y].fa;
int yson=ident(x),zson=ident(y);
change(t[x].son[yson^1],y,yson);
change(y,x,yson^1);
change(x,z,zson);
pushup(y);pushup(x);
}
void splay(int x,int goal)
{
goal=t[goal].fa;
while(t[x].fa!=goal)
{
int y=t[x].fa;
if(t[y].fa==goal)rotate(x);
else if(ident(x)==ident(y))rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
void insert(int x)
{
int now=root;
if(root==0){t[++tot].init(x,0);root=tot;}
else while(1)
{
t[now].siz++;
if(t[now].val==x){t[now].cnt++;splay(now,root);}
int nxt=x<t[now].val?0:1;
if(!t[now].son[nxt])
{
t[++tot].init(x,now);
t[now].son[nxt]=tot;
splay(tot,root);
return ;
}
now=t[now].son[nxt];
}
}
int querynxt(int x)
{
int now=root,ans=INF;
while(now)
{
if(t[now].val>=x)ans=min(ans,t[now].val);
int nxt=t[now].val>x?0:1;
now=t[now].son[nxt];
}
return ans;
}
int querypre(int x)
{
int now=root,ans=-INF;
while(now)
{
if(t[now].val<=x)ans=max(ans,t[now].val);
int nxt=t[now].val>x?0:1;
now=t[now].son[nxt];
}
return ans;
}
}T;
int main()
{
int n=read();
int x=read(),ans=x;
T.insert(x);
for(int i=1;i<n;i++)
{
x=read();
int a=T.querypre(x),b=T.querynxt(x);
ans+=min(abs(x-a),abs(x-b));
// cout<<a<<' '<<b<<endl;
// cout<<"ans="<<ans<<endl;
T.insert(x);
}
printf("%d",ans);
}