版权声明:转载记得声明噢! https://blog.csdn.net/Richard__Luan/article/details/82191914
传送门
平衡树求前驱和后继,可以用set
AC code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct Treap
{
int l,r,key,size,w,rnd;
}T[33005];
int root,n,size,ans;
const int rndd=2000000001;
int tot;
void update(int k)
{
T[k].size=T[T[k].l].size+T[T[k].r].size+T[k].w;
}
void zig(int &k)
{
int t=T[k].r;
T[k].r=T[t].l;
T[t].l=k;
T[t].size=T[k].size;
update(k);
k=t;
}
void zag(int &k)
{
int t=T[k].l;
T[k].l=T[t].r;
T[t].r=k;
T[t].size=T[k].size;
update(k);
k=t;
}
void insert(int &k,int x)
{
if(!k)
{
size++;
k=size;
T[k].size=T[k].w=1;
T[k].rnd=rand();
T[k].key=x;
return ;
}
T[k].size++;
if(T[k].key==x)
{
T[k].w++;
return ;
}
if(T[k].key>x)
{
insert(T[k].l,x);
if(T[T[k].l].rnd<T[k].rnd)zag(k);
}
else
{
insert(T[k].r,x);
if(T[T[k].r].rnd<T[k].rnd)zig(k);
}
}
void query_sub(int &k,int x)
{
//cout<<k<<" "<<T[k].key<<endl;
if(!k)return ;
if(x==T[k].key)
{
ans=x;
return ;
}
if(x<T[k].key)
{
ans=T[k].key;
//cout<<ans<<"a"<<endl;
query_sub(T[k].l,x);
}
else query_sub(T[k].r,x);
}
void query_pro(int &k,int x)
{
//cout<<k<<" "<<T[k].key<<endl;
if(!k)return ;
if(x==T[k].key)
{
ans=x;
return ;
}
if(x>T[k].key)
{
ans=T[k].key;
//cout<<ans<<"b"<<endl;
query_pro(T[k].r,x);
}
else query_pro(T[k].l,x);
}
int main()
{
srand(21323123);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
//cout<<"x";
int x;
scanf("%d",&x);
if(i==1)
{
insert(root,x);
tot+=x;
continue;
}
int minn=2000000000;
ans=rndd;
query_pro(root,x);
if(ans!=rndd)
minn=min(minn,abs(ans-x));
//cout<<ans<<endl;
ans=rndd;
query_sub(root,x);
if(ans!=rndd)
minn=min(minn,abs(ans-x));
//cout<<ans<<endl;
tot+=minn;
insert(root,x);
//cout<<root<<endl;
//cout<<tot<<"s"<<endl;
}
printf("%d",tot);
return 0;
}