左偏树

模板:

 

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
int n, m, heap[MAXN];
int fa[MAXN], ls[MAXN], rs[MAXN], dis[MAXN];
bool del[MAXN];

int find(int x) {
     return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int Merge(int u, int v) {
    if(!u || !v) return u+v;
    if(heap[u]==heap[v]? u>v :heap[u]>heap[v]) swap(u,v);//相等比较u和V,否则比较heap[u]和heap[v] 
    rs[u]=Merge(rs[u],v);
    if(dis[rs[u]] > dis[ls[u]])  swap(ls[u],rs[u]);
    dis[u]=dis[rs[u]]+1;
    fa[ls[u]]=fa[rs[u]]=u;
    return u;
     
}

void pop(int u) {
    del[u]=true;
    fa[rs[u]]=rs[u];
    fa[ls[u]]=ls[u];
    fa[u]=Merge(ls[u],rs[u]);
   
}

void init() {
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    
}

P3377:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
int n, m, heap[MAXN];
int fa[MAXN], ls[MAXN], rs[MAXN], dis[MAXN];
bool del[MAXN];

int find(int x) {
     return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int Merge(int u, int v) {
    if(!u || !v) return u+v;
    if(heap[u]==heap[v]? u>v :heap[u]>heap[v]) swap(u,v);//相等比较u和V,否则比较heap[u]和heap[v] 
    rs[u]=Merge(rs[u],v);
    if(dis[rs[u]] > dis[ls[u]])  swap(ls[u],rs[u]);
    dis[u]=dis[rs[u]]+1;
    fa[ls[u]]=fa[rs[u]]=u;
    return u;
     
}

void pop(int u) {
    del[u]=true;
    fa[rs[u]]=rs[u];
    fa[ls[u]]=ls[u];
    fa[u]=Merge(ls[u],rs[u]);
   
}

void init() {
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    
}


int main() {
    dis[0] = -1;
    // 注意!此处是为了保证叶子节点 dis = 0
    scanf("%d %d", &n, &m);
    init();
    for (int i = 1; i <= n; i++)
        scanf("%d", &heap[i]);
    for (int opt, x, y; m; m--) {
        scanf("%d", &opt);
        if (opt == 1) {
            scanf("%d %d", &x, &y);
            if (del[x] || del[y])
                continue;//返回for循环 
            x = find(x), y = find(y);
            if (x != y) 
                fa[x] = fa[y] = Merge(x, y);
        } else {
            scanf("%d", &x);
            if (del[x]) {
                printf("-1\n");
                continue;
            }
            x = find(x);
            printf("%d\n", heap[x]);
            pop(x);
        }
    }
    return 0;
}

P1456:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100010;
int n, m, heap[MAXN];
int fa[MAXN], ls[MAXN], rs[MAXN], dis[MAXN];

int find(int x) {
     return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int Merge(int u, int v) {
    if(!u || !v) return u+v;
    if(heap[u]<heap[v]) swap(u,v);//相等比较u和V,否则比较heap[u]和heap[v] 
    rs[u]=Merge(rs[u],v);
    if(dis[rs[u]] > dis[ls[u]])  swap(ls[u],rs[u]);
    dis[u]=dis[rs[u]]+1;
    fa[ls[u]]=fa[rs[u]]=u;
    return u;
     
}


void init() {
    for(int i=1;i<=n;i++){
        ls[i]=rs[i]=dis[i]=0;
        fa[i]=i;
    }
    
}

int main(){
    dis[0]=-1;
    while (~scanf("%d",&n))
    {    
    init();
    for(int i=1;i<=n;i++){
        cin>>heap[i];
    }
    cin>>m;
    while(m--)
    {
        int x,y;
        cin>>x>>y;
        if(find(x)==find(y)){
            cout<<"-1"<<endl;
        }
        else{
            x=find(x);
            y=find(y);
            heap[x]=heap[x]/2;
            heap[y]=heap[y]/2;
            int i,j,p,q,final;
    
            i=Merge(ls[x],rs[x]);
            ls[x]=rs[x]=dis[x]=0;//将根节点断掉 
            
            j=Merge(i,x);
            fa[i]=fa[x]=j;//为了路径压缩,要将旧根和子树合并的根都指向新根 
            
            p=Merge(ls[y],rs[y]);
            ls[y]=rs[y]=dis[y]=0;
            q=Merge(p,y);
            fa[p]=fa[y]=q;
            
            final=Merge(j,q);
            fa[j]=fa[q]=final;
            cout<<heap[final]<<endl;
            //自己写的,有问题,没有将根点断掉 
           /* x=find(x);
            y=find(y);
            heap[x]=heap[x]/2;
            heap[y]=heap[y]/2;
            int i,j,p,q,final;
            fa[rs[x]]=rs[x];
            fa[ls[x]]=ls[x];
            fa[rs[y]]=rs[y];
            fa[ls[y]]=ls[y];
            
            i=Merge(ls[x],rs[x]);
            j=Merge(i,x);
            fa[i]=fa[x]=j;
            
            p=Merge(ls[y],rs[y]);
            q=Merge(p,y);
            fa[p]=fa[y]=q;
            
            final=Merge(j,q);
            fa[j]=fa[q]=final;
            cout<<heap[final]<<endl;;*/
        }
    }
        
    }
    
    return 0;
}

 

posted @ 2023-07-05 22:51  zipzipzipper  阅读(37)  评论(0)    收藏  举报