BZOJ 1588 平衡树 模板题

Treap:

//By SiriusRen
#include <cstdio>
#include <algorithm>
using namespace std;
int size,n,xx,root,ans,tmp;
struct Treap{int ch[2],v,cnt,rnd,sz;}tr[500050];
void Upd(int k){tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz+tr[k].cnt;}
void rot(int &k,bool f){int t=tr[k].ch[f];tr[k].ch[f]=tr[t].ch[!f],tr[t].ch[!f]=k,Upd(k),Upd(t),k=t;}
void insert(int &k,int num){
    if(!k){k=++size,tr[k].cnt=tr[k].sz=1,tr[k].rnd=rand(),tr[k].v=num;return;}
    tr[k].sz++;
    if(tr[k].v==num){tr[k].cnt++;return;}
    bool f=num>tr[k].v;
    insert(tr[k].ch[f],num);
    if(tr[tr[k].ch[f]].rnd<tr[k].rnd)rot(k,f);
}
void pre(int k,int num){
    if(!k)return;
    if(tr[k].v==num)tmp=0;
    else if(tr[k].v>num)tmp=min(tmp,tr[k].v-num),pre(tr[k].ch[0],num);
    else pre(tr[k].ch[1],num);
}
void nxt(int k,int num){
    if(!k)return;
    if(tr[k].v==num)tmp=0;
    else if(tr[k].v<num)tmp=min(tmp,num-tr[k].v),nxt(tr[k].ch[1],num);
    else nxt(tr[k].ch[0],num);
}
int main(){
    scanf("%d%d",&n,&xx);
    insert(root,xx),ans+=xx;
    for(int i=1;i<n;i++){
        scanf("%d",&xx);
        tmp=0x3fffffff,pre(root,xx),nxt(root,xx);
        ans+=tmp,insert(root,xx);
    }
    printf("%d\n",ans);
}

这里写图片描述

Splay:

//By SiriusRen
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 33333
#define inf 0x3f3f3f3f
#define lc(x) ch[(x)][0]
#define rc(x) ch[(x)][1]
int n,fa[N],ch[N][2],root,k[N],ind=1,xx,ans;
void rotate(int p){
    int q=fa[p],y=fa[q],x=ch[q][1]==p;
    ch[q][x]=ch[p][x^1];fa[ch[q][x]]=q;
    ch[p][x^1]=q;fa[q]=p;
    fa[p]=y;
    if(y){
        if(ch[y][0]==q)ch[y][0]=p;
        else ch[y][1]=p;
    }
}
void splay(int x){
    for(int y;y=fa[x];rotate(x))
        if(fa[y]){
            if((y==lc(fa[y])&&x==lc(y))||(y==rc(fa[y])&&x==rc(y)))rotate(y);
            else rotate(x);
        }
    root=x;
}
void insert(int x,int v){
    while(ch[x][k[x]<v])x=ch[x][k[x]<v];
    ch[x][k[x]<v]=++ind;
    fa[ind]=x,k[ind]=v,splay(ind);
}
int pre(int x){
    int tmp=ch[x][0];
    while(ch[tmp][1])tmp=ch[tmp][1];
    return k[tmp];
}
int suc(int x){
    int tmp=ch[x][1];
    while(ch[tmp][0])tmp=ch[tmp][0];
    return k[tmp];
}
int main(){
    scanf("%d",&n);
    insert(root,inf),insert(root,-inf);
    scanf("%d",&xx);insert(root,xx);
    ans=xx;
    for(int i=2;i<=n;i++){
        scanf("%d",&xx);
        insert(root,xx);
        int a=pre(root),b=suc(root);
        ans+=min(xx-a,b-xx);
    }
    printf("%d\n",ans);
}

这里写图片描述

posted @ 2017-01-02 09:24  SiriusRen  阅读(173)  评论(0编辑  收藏  举报