1.treap
一棵treap维护一下就可以了吧(压行导致代码格式不怎么美观)
#include<cstdio> #include<cctype> #include<cmath> #include<algorithm> #define maxn 32770 using namespace std; struct data{int l,r,rnd,siz,key;data(){l=r=key=0;siz=1;};}tr[maxn]; int n,rt,tmp,siz; long long ans; void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } void rturn(int &x){int tmp=tr[x].l;tr[x].l=tr[tmp].r;tr[tmp].r=x;tr[tmp].siz=tr[x].siz;tr[x].siz=tr[tr[x].l].siz+1+tr[tr[x].r].siz;x=tmp;} void lturn(int &x){int tmp=tr[x].r;tr[x].r=tr[tmp].l;tr[tmp].l=x;tr[tmp].siz=tr[x].siz;tr[x].siz=tr[tr[x].l].siz+1+tr[tr[x].r].siz;x=tmp;} void insert(int x,int &rt){ if(!rt){rt=++siz;tr[siz].key=x;tr[siz].rnd=rand();return;} tmp=min(tmp,abs(x-tr[rt].key)); if(x<tr[rt].key){tr[rt].siz++;insert(x,tr[rt].l);if(tr[tr[rt].l].rnd>tr[rt].rnd)rturn(rt);} else if(x>tr[rt].key){tr[rt].siz++;insert(x,tr[rt].r);if(tr[tr[rt].r].rnd>tr[rt].rnd);lturn(rt);} } int main(){ read(n);int x; for(int i=1;i<=n;i++){ read(x);tmp=1e9;insert(x,rt); ans+=(i==1?abs(x):tmp); } printf("%lld",ans); }
2.splay
挺快的
#include<cstdio> #include<cctype> #include<algorithm> #define maxn 300002 using namespace std; int fa[maxn],tr[maxn][2],rt,key[maxn],siz=1; void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } inline void rotate(int x){ int f=fa[x],gfa=fa[f],whicx=tr[f][1]==x; tr[f][whicx]=tr[x][whicx^1];fa[tr[f][whicx]]=f; tr[x][whicx^1]=f;fa[f]=x; fa[x]=gfa; if(gfa){if(tr[gfa][0]==f)tr[gfa][0]=x;else if(tr[gfa][1]==f)tr[gfa][1]=x;} } inline void splay(int x){ for(int y;y=fa[x];rotate(x)) if(fa[y])rotate((x==tr[y][0])==(y==tr[fa[y]][0])?y:x); rt=x; } inline void insert(int root,int x){ int y; while(1){ y=tr[root][key[root]<x]; if(!y){ y=++siz; key[y]=x;tr[y][0]=tr[y][1]=0;fa[y]=root;tr[root][key[root]<x]=y; break; } root=y; } splay(y); } inline int pre(int x){ int tmp=tr[x][0];while(tr[tmp][1])tmp=tr[tmp][1];return key[tmp]; } inline int suc(int x){ int tmp=tr[x][1];while(tr[tmp][0])tmp=tr[tmp][0];return key[tmp]; } int main(){ int n,x,ans=0; read(n); if(n==0){printf("0");return 0;} read(x); rt=1;key[rt]=x;tr[rt][0]=tr[rt][1]=0;fa[rt]=0; ans=abs(x); insert(rt,1e9);insert(rt,-1e9); for(int i=1;i<n;i++){ read(x);insert(rt,x); int qq=pre(rt),hj=suc(rt); ans+=min(x-qq,hj-x); } printf("%d",ans); }