BZOJ 1588 平衡树 模板题

来源:互联网 发布:人工智能导论 编辑:程序博客网 时间:2024/06/06 18:19

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);}

这里写图片描述

0 0
原创粉丝点击