splay树板子

//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 100000
using namespace std;
const int inf=1e9;
int n,x,mini,maxx,ans,root,cnt,fa[N],tr[N][2],t[N+N+N+N];

inline void rotate(int p,int &k)
{
    int f=fa[p],ff=fa[f],l,r;
    if(tr[f][0]==p) l=0;else l=1;
    r=l ^ 1;
    if(f==k) k=p;
    else{
        if(tr[ff][0]==f) tr[ff][0]=p;else tr[ff][1]=p;
    }
    fa[p]=ff;
    fa[f]=p;
    fa[tr[p][r]]=f;
    tr[f][l]=tr[p][r];
    tr[p][r]=f;
}

inline void splay(int p,int &k)
{
    while(p != k){
        if(fa[p] != k){
            if((tr[fa[fa[p]]][1]==fa[p]) ^ (tr[fa[p]][0]==p)) rotate(p,k);
            else rotate(fa[p],k);
        }
        rotate(p,k);
    }
}

void insert(int key,int &k,int father)
{
    if(!k){
        k=++cnt;
        t[k]=key;
        fa[k]=father;
        splay(k,root);
        return;
    }
    else if(t[k]<=key) insert(key,tr[k][1],k);
    else insert(key,tr[k][0],k);
}

void find1(int key,int k)    // 寻找左子树中最大的
{
    if(!k) return;
    if(t[k]<=key){maxx=t[k];find1(key,tr[k][1]);}
    else find1(key,tr[k][0]);
}

void find2(int key,int k)    // 寻找右子树中最小的。
{
    if(!k) return;
    if(t[k]>=key){mini=t[k];find2(key,tr[k][0]);}
    else find2(key,tr[k][1]);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        mini=inf;maxx=-inf;
        find1(x,root);find2(x,root);
        if(i>1) ans+=min(x-maxx,mini-x);else ans+=x;
        insert(x,root,-1);
    }
    printf("%d
",ans);
    return 0;
}
rush!
原文地址:https://www.cnblogs.com/LH2000/p/14833060.html