其实这个题不用平衡树也可以过的??(数据太水了啊)
但是我还是本着联系平衡树的想法打了一遍平衡树。
既然是最小的波动,那么直接找前驱后继就可以了呀qwq
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,m,root,tot;
long long ans;
struct Node{int fa,val,ch[2],cnt;}t[MAXN<<2];
inline void rotate(int x)
{
int y=t[x].fa;
int z=t[y].fa;
int k=t[y].ch[1]==x;
t[z].ch[t[z].ch[1]==y]=x; t[x].fa=z;
t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].fa=y;
t[x].ch[k^1]=y; t[y].fa=x;
}
inline void splay(int x,int goal)
{
while(t[x].fa!=goal)
{
int y=t[x].fa;
int z=t[y].fa;
if(z!=goal)
((t[y].ch[0]==x)^(t[z].ch[0]==y))?rotate(x):rotate(y);
rotate(x);
}
if(!goal) root=x;
}
inline void find(int x)
{
int u=root;
if(!u) return;
while(t[u].ch[t[u].val<x]&&x!=t[u].val)
u=t[u].ch[t[u].val<x];
splay(u,0);
}
inline int pre(int x,int f)
{
find(x);
int u=root;
if((t[u].val<=x&&!f)||(t[u].val>=x&&f)) return u;
u=t[u].ch[f];
while(t[u].ch[f^1]) u=t[u].ch[f^1];
return u;
}
inline void insert(int x)
{
int u=root,ff=0;
while(u&&t[u].val!=x)
ff=u,u=t[u].ch[t[u].val<x];
if(u) t[u].cnt++;
else
{
u=++tot;
if(ff) t[ff].ch[t[ff].val<x]=u;
t[tot].fa=ff,t[tot].cnt=1,t[tot].val=x;
}
splay(u,0);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
insert(-2147483627);insert(2147483627);
scanf("%d",&ans);
insert(ans);
for(int i=2;i<=n;i++)
{
int cur;
scanf("%d",&cur);
ans+=min(abs(t[pre(cur,0)].val-cur),abs(t[pre(cur,1)].val-cur));
insert(cur);
}
printf("%lld
",ans);
return 0;
}