原来treap这么简单。。。比splay简单多了。。。。
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; int n,a; struct Node { Node *ch[2]; int r,v; Node() { ch[0]=ch[1]=NULL; r=rand();v=0; } };Node *rt; void Free(Node *o) { if(o==NULL) return; Free(o->ch[0]); Free(o->ch[1]); delete o; } void rot(Node* &o,int d) { Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o=k; } void Insert(Node* &o,int x) { if(o==NULL){ o=new Node(); o->v=x; return; } if(o->v==x) return; int d=x<o->v?0:1; Insert(o->ch[d],x); if(o->ch[d]->r>o->r) rot(o,d^1); } int Find(Node* &o,int x) { if(o==NULL) return 0; if(o->v==x) return 1; if(x<o->v) return Find(o->ch[0],x); else return Find(o->ch[1],x); } int getpre(Node* &o,int x) { if(o==NULL) return -INF; if(x<=o->v) return getpre(o->ch[0],x); else return max(o->v,getpre(o->ch[1],x)); } int getnext(Node* &o,int x) { if(o==NULL) return INF; if(x>=o->v) return getnext(o->ch[1],x); else return min(o->v,getnext(o->ch[0],x)); } int main() { //freopen("in.txt","r",stdin); while(cin>>n){ Free(rt); int ans=0; REP(i,1,n){ if(scanf("%d",&a)==EOF) a=0; if(i==1) ans+=a; else{ int b=Find(rt,a); if(b==1) ; else{ int x=getpre(rt,a),y=getnext(rt,a); ans+=min(a-x,y-a); } } Insert(rt,a); } cout<<ans<<endl; Free(rt); } return 0; }