洛谷P2073送花

#include<cstdio>
#define mid(l,r) ((l+r)/2)
#define MXN 10000+1
#define nil 0
#define alpha 0.7f
int read(){
    int x=0;
    bool w=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') w=0;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<3)+(x<<1)+(c-'0');
        c=getchar();
    }
    return w?x:-x;
}
void write(long long x){
    int buf[20],p=-1;
    if(x<0){
        putchar('-');
        x=-x;
    }
    while(x){
        buf[++p]=x%10;
        x/=10;
    }
    if(p==-1) putchar('0');
    else for(int i=p;i>=0;i--) putchar(buf[i]+'0');
    return;
}
int valw[MXN],valc[MXN],size[MXN],fa[MXN],left[MXN],right[MXN],recycle[MXN],lst[MXN];
int root,ntop,rtop=-1,ltop;
int p,x,y;
long long wans,cans;
void grand_travel(int now,const char* link){
    if(now==nil) return;
    grand_travel(left[now],link);
    printf("%d",now);
    printf(link);
    grand_travel(right[now],link);
    return;
}
int newnode(){
    int nw;
    if(rtop!=-1) nw=recycle[rtop--];
    else nw=++ntop;
    valw[nw]=0;
    valc[nw]=0;
    size[nw]=1;
    fa[nw]=nil;
    left[nw]=nil;
    right[nw]=nil;
    return nw;
}
int newnode(int a,int b){
    int nw=newnode();
    valw[nw]=a;
    valc[nw]=b;
    return nw;
}
int search(int now,int c){
    if(now==nil) return nil;
    if(valc[now]==c) return now;
    if(valc[now]>c) return search(left[now],c);
    if(valc[now]<c) return search(right[now],c);
}
bool check(int now){
    return size[left[now]]>size[now]*alpha||size[right[now]]>size[now]*alpha;
}
void travel(int now){
    if(now==nil) return;
    travel(left[now]);
    lst[ltop++]=now;
    travel(right[now]);
    return;
}
int build(int l,int r){
    if(l>=r) return nil;
    int mid=mid(l,r),nw=lst[mid];
    left[nw]=build(l,mid);
    right[nw]=build(mid+1,r);
    fa[left[nw]]=nw;
    fa[right[nw]]=nw;
    size[nw]=size[left[nw]]+size[right[nw]]+1;
    return nw;
}
void insert(int &now,int ins){
    if(root==nil) root=ins;
    else if(now==nil) now=ins;
    else{
        size[now]++;
        if(valc[ins]<valc[now]){
            if(left[now]==nil){
                left[now]=ins;
                fa[ins]=now;
            }
            else insert(left[now],ins);
        }
        else{
            if(right[now]==nil){
                right[now]=ins;
                fa[ins]=now;
            }
            else insert(right[now],ins);
        }
    }
    return;
}
void add(int w,int c){
    if(search(root,c)!=nil) return;
    int ins=newnode(w,c);
    insert(root,ins);
    int t=0,f,flag,rt;
    for(int i=ins;fa[i]!=nil;i=fa[i]){
        if(check(i)) t=i;
    }
    if(t){
        ltop=0;
        f=fa[t];
        if(left[f]==t) flag=1;
        else flag=0;
        travel(t);
        rt=build(0,ltop);
        if(t==root) root=rt;
        else{
            fa[rt]=f;
            if(flag) left[f]=rt;
            if(!flag) right[f]=rt;
        }
    }
    return;
}
void remove(bool flag){
    if(root==nil) return;
    int t=root;
    if(flag==false){
        while(left[t]!=nil){
            size[t]--;
            t=left[t];
        }
    }
    else{
        while(right[t]!=nil){
            size[t]--;
            t=right[t];
        }
    }
    if(left[t]==nil&&right[t]==nil){
        if(left[fa[t]]==t) left[fa[t]]=nil;
        else right[fa[t]]=nil;
        if(root==t) root=nil;
        fa[t]=nil;
        recycle[++rtop]=t;
        return;
    }
    else if(left[t]==nil){
        if(left[fa[t]]==t) left[fa[t]]=right[t];
        else right[fa[t]]=right[t];
        fa[right[t]]=fa[t];
        if(root==t) root=right[t];
        fa[t]=nil;
        recycle[++rtop]=t;
        return;
    }
    else if(right[t]==nil){
        if(left[fa[t]]==t) left[fa[t]]=left[t];
        else right[fa[t]]=left[t];
        fa[left[t]]=fa[t];
        if(root==t) root=left[t];
        fa[t]=nil;
        recycle[++rtop]=t;
        return;
    }
    return;
}
void grand_order(int now){
    if(now==nil) return;
    grand_order(left[now]);
    wans+=valw[now];
    cans+=valc[now];
    grand_order(right[now]);
    return;
}
int main(){
    root=nil;
    while(1){
        p=read();
        if(p==-1) break;
        if(p==1){
            x=read();
            y=read();
            add(x,y);
        }
        if(p==3) remove(false);
        if(p==2) remove(true);
    }
    grand_order(root);
    write(wans);
    putchar(' ');
    write(cans);
    return 0;
}
代码

题意请上洛谷。

这是一道平衡树水题。上周末做了Code+的第二次月赛,平衡树那道题没有做出来后,我就感觉要做一些题练习练习。

总之就是一道裸题。以上代码是用我很喜欢的替罪羊树写的,表达一下我的心情,虽然替罪羊树只有平衡树基本的应用。不过替罪羊真的跑得飞快啊。

近来发现Treap好强啊,几乎支持现在所有操作了,还能可持久化……

看来需要学习Treap。

#include<cstdio>
#define abs(x) (x>0?x:-x)
#define MXN 100000+1
#define nil 0
#define alpha 0.5f
int val[MXN],size[MXN],fa[MXN],left[MXN],right[MXN],recycle[MXN];
int root,ntop,rtop=-1;
int newnode(){
    int nw;
    if(rtop==-1) nw=++ntop;
    else nw=recycle[rtop--];
    val[nw]=0;
    size[nw]=1;
    fa[nw]=nil;
    left[nw]=nil;
    right[nw]=nil;
    return nw;
}
int newnode(int k){
    int nw=newnode();
    val[nw]=k;
    return nw;
}
bool check(int now){
    int a=size[left[now]]-size[right[now]];
    return abs(a)>alpha*size[now];
}
void rotate(int now){
    if(fa[now]==nil) return;
    int f=fa[now],gf=fa[f],l=left[now],r=right[now];
    if(left[gf]==f) left[gf]=now;
    else right[gf]=now;
    if(left[f]==now){
        right[now]=f;
        left[f]=r;
        fa[r]=f;
    }
    else{
        left[now]=f;
        right[f]=l;
        fa[l]=f;
    }
    fa[f]=now;
    fa[now]=gf;
    size[f]=size[left[f]]+size[right[f]]+1;
    size[now]=size[left[now]]+size[right[now]]+1;
    if(fa[now]==nil) root=now;
    return;
}
void adjust(int now){
    if(check(now)){
        if(size[left[now]]>size[right[now]]) rotate(left[now]);
        else rotate(right[now]);
    }
    return;
}
void insert(int &now,int ins){
    if(root==nil) root=ins;
    else if(now==nil) now=ins;
    else{
        size[now]++;
        if(val[ins]<val[now]){
            if(left[now]==nil){
                left[now]=ins;
                fa[ins]=now;
            }
            else insert(left[now],ins);
        }
        else{
            if(right[now]==nil){
                right[now]=ins;
                fa[ins]=now;
            }
            else insert(right[now],ins);
        }
    }
    adjust(now);
    return;
}
void remove(int now,int k){
    if(now==nil) return;
    if(k==val[now]){
        if(left[now]==nil&&right[now]==nil){
            if(left[fa[now]]==now) left[fa[now]]=nil;
            else right[fa[now]]=nil;
            if(now==root) root=nil;
            fa[now]=nil;
            recycle[++rtop]=now;
            return;
        }
        else if(left[now]==nil){
            if(left[fa[now]]==now) left[fa[now]]=right[now];
            else right[fa[now]]=right[now];
            fa[right[now]]=fa[now];
            if(now==root) root=right[now];
            fa[now]=nil;
            recycle[++rtop]=now;
            return;
        }
        else if(right[now]==nil){
            if(left[fa[now]]==now) left[fa[now]]=left[now];
            else right[fa[now]]=left[now];
            fa[left[now]]=fa[now];
            if(now==root) root=left[now];
            fa[now]=nil;
            recycle[++rtop]=now;
            return;
        }
        else{
            int t=left[now];
            while(right[t]!=nil) t=right[t];
            val[now]=val[t];
            size[now]--;
            remove(left[now],val[t]);
            adjust(now);
        }
    }
    else{
        size[now]--;
        if(k<val[now]) remove(left[now],k);
        else remove(right[now],k);
        adjust(now);
    }
    return;
}
int search(int now,int k){
    if(now==nil) return nil;
    if(k==val[now]) return now;
    if(k<val[now]) return search(left[now],k);
    if(k>val[now]) return search(right[now],k);
}
void grand_order(int now){
    if(now==nil) return;
    grand_order(left[now]);
    printf("%d ",val[now]);
    grand_order(right[now]);
    return;
}
int main(){
    root=nil;
    while(1){
        int p,x;
        scanf("%d",&p);
        if(p==1){
            scanf("%d",&x);
            if(search(root,x)==nil) insert(root,newnode(x));
        }
        if(p==2){
            scanf("%d",&x);
            if(search(root,x)!=nil) remove(root,x);
        }
        if(p==3){
            grand_order(root);
            printf("
");
        }
        if(p==0) break;
    }
    return 0;
}
代码2

另一种平衡树A了。

#include<cstdio>
#define MXN 100000+1
#define nil 0
int read(){
    int x=0;
    bool w=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') w=0;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<3)+(x<<1)+(c-'0');
        c=getchar();
    }
    return w?x:-x;
}
void write(long long x){
    int buf[20],p=-1;
    if(x<0){
        putchar('-');
        x=-x;
    }
    while(x){
        buf[++p]=x%10;
        x/=10;
    }
    if(p==-1) putchar('0');
    else for(int i=p;i>=0;i--) putchar(buf[i]+'0');
    return;
}
int random(){
    static int seed=707;
    return seed=int(seed*48721LL&2147483647);
}
int valw[MXN],valc[MXN],rnd[MXN],fa[MXN],left[MXN],right[MXN],recycle[MXN];
int root,ntop,rtop=-1;
long long wans,cans;
int newnode(){
    int nw;
    if(rtop==-1) nw=++ntop;
    else nw=recycle[rtop--];
    valw[nw]=0;
    valc[nw]=0;
    rnd[nw]=random();
    fa[nw]=nil;
    left[nw]=nil;
    right[nw]=nil;
    return nw;
}
int newnode(int w,int c){
    int nw=newnode();
    valw[nw]=w;
    valc[nw]=c;
    return nw;
}
void rotate(int now){
    if(fa[now]==nil) return;
    int f=fa[now],gf=fa[f],l=left[now],r=right[now];
    if(left[gf]==f) left[gf]=now;
    else right[gf]=now;
    if(left[f]==now){
        right[now]=f;
        left[f]=r;
        fa[r]=f;
    }
    else{
        left[now]=f;
        right[f]=l;
        fa[l]=f;
    }
    fa[f]=now;
    fa[now]=gf;
    if(fa[now]==nil) root=now;
    return;
}
void insert(int &now,int ins){
    if(root==nil) root=ins;
    else if(now==nil) now=ins;
    else{
        if(valc[ins]<valc[now]){
            if(left[now]==nil){
                left[now]=ins;
                fa[ins]=now;
            }
            else insert(left[now],ins);
        }
        else{
            if(right[now]==nil){
                right[now]=ins;
                fa[ins]=now;
            }
            else insert(right[now],ins);
        }
    }
    return;
}
void remove(bool flag){
    if(root==nil) return;
    int t=root;
    if(flag==false){
        while(left[t]!=nil){
            t=left[t];
        }
    }
    else{
        while(right[t]!=nil){
            t=right[t];
        }
    }
    if(left[t]==nil&&right[t]==nil){
        if(left[fa[t]]==t) left[fa[t]]=nil;
        else right[fa[t]]=nil;
        if(root==t) root=nil;
        fa[t]=nil;
        recycle[++rtop]=t;
        return;
    }
    else if(left[t]==nil){
        if(left[fa[t]]==t) left[fa[t]]=right[t];
        else right[fa[t]]=right[t];
        fa[right[t]]=fa[t];
        if(root==t) root=right[t];
        fa[t]=nil;
        recycle[++rtop]=t;
        return;
    }
    else if(right[t]==nil){
        if(left[fa[t]]==t) left[fa[t]]=left[t];
        else right[fa[t]]=left[t];
        fa[left[t]]=fa[t];
        if(root==t) root=left[t];
        fa[t]=nil;
        recycle[++rtop]=t;
        return;
    }
    return;
}
int search(int now,int k){
    if(now==nil) return nil;
    if(k==valc[now]) return now;
    if(k<valc[now]) return search(left[now],k);
    if(k>valc[now]) return search(right[now],k);
}
void grand_order(int now){
    if(now==nil) return;
    grand_order(left[now]);
    wans+=valw[now];
    cans+=valc[now];
    grand_order(right[now]);
    return;
}
int main(){
    root=nil;
    wans=0;
    cans=0;
    int p,x,y;
    while(1){
        p=read();
        if(p==-1) break;
        if(p==1){
            x=read();
            y=read();
            if(search(root,y)==nil){
                int ins=newnode(x,y);
                insert(root,ins);
                while(rnd[ins]<rnd[fa[ins]]&&fa[ins]!=nil) rotate(ins);
            }
        }
        if(p==3) remove(false);
        if(p==2) remove(true);
    }
    grand_order(root);
    write(wans);
    putchar(' ');
    write(cans);
    return 0;
}
代码3

带旋TreapAC代码。

原文地址:https://www.cnblogs.com/halifuda/p/8118941.html