SCUT - 278 - Puzzle # 020 - leftist tree

https://scut.online/p/278
first encounter do not need to check and set the leftist tree.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int n,m;
const int MAXN=1000005;
int tot,v[MAXN],l[MAXN],r[MAXN],d[MAXN];
int gc[MAXN];   //gc[i]表示编号为i的工厂所在的左偏树是哪个x

class Leftist_Tree {
    inline int _Merge(int x,int y) {
        if(!x||!y)
            return x+y;
        //<就是大顶堆
        if(v[x]<v[y])
            swap(x,y);
        r[x]=_Merge(r[x],y);
        if(d[l[x]]<d[r[x]])
            swap(l[x],r[x]);
        d[x]=d[r[x]]+1;
        return x;
    }
    inline int Build(int val=-1) {
        tot++;
        l[tot]=r[tot]=d[tot]=0;
        v[tot]=val;
        return tot;
    }
  public:
    inline void Init() {
        tot=0;
        v[0]=-1;
        //memset(gc,0,sizeof(gc));多组数据时要把工厂指回空树
    }
    inline void Push(int &x,int &val) {
        //向x工厂加入节点val
        int rt=Build(val);
        gc[x]=_Merge(rt,gc[x]);
    }
    inline int Pop(int &x) {
        //把x工厂的顶端弹出,没有顶端弹出v[0],那个节点还在只不过失联了而已
        int gcx=gc[x];
        gc[x]=_Merge(l[gcx],r[gcx]);
        return v[gcx];
    }
    inline void Merge(int &x,int &y) {
        //把y工厂合并到x工厂
        gc[x]=_Merge(gc[x],gc[y]);
        gc[y]=Build();
    }
} lt;

inline int read() {
    int x=0;
    char c;
    do {
        c=getchar();
    } while(c<'0'||c>'9');
    do {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    } while(c>='0'&&c<='9');
    return x;
}

inline void _write(int x) {
    if(x>9)
        _write(x/10);
    putchar(x%10+'0');
}

inline void write(int x) {
    if(x<0) {
        putchar('-');
        x=-x;
    }
    _write(x);
    putchar('\n');
}

int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
#endif // Yinku
    int n=read(),m=read();
    lt.Init();
    for(int i=1; i<=m; i++) {
        int ins=read();
        switch(ins) {
            case 1: {
                int x=read(),v=read();
                lt.Push(x,v);
                break;
            }
            case 2: {
                int x=read(),y=read();
                lt.Merge(x,y);
                break;
            }
            case 3: {
                int x=read();
                //printf("%d\n",lt.Pop(x));
                write(lt.Pop(x));
                break;
            }
        }
    }
}

Guess you like

Origin www.cnblogs.com/Yinku/p/11028289.html