洛谷3377

国家集训队论文

推荐一篇好的博文

左偏树博文

dis表示该点到最近叶子节点经过的路

#include<cstdio>
#include<cctype>
#define maxn 100001
using namespace std;
int n,m,val[maxn],dis[maxn],f[maxn],tr[maxn][2];

inline void swap(int &x,int &y){int t=x;x=y;y=t;}


inline void read(int &x){
    char ch=getchar();x=0;
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
}
//一定要注意这里findfa不能过程中合并,否则删点时会出问题
inline int findfa(int x){
    while(f[x])x=f[x];return x;
}

inline int merge(int x,int y){
    if(x==0||y==0)return x+y;
    if(val[x]>val[y]||(val[x]==val[y]&&x>y))swap(x,y);
    tr[x][1]=merge(tr[x][1],y);
    f[tr[x][1]]=x;
    if(dis[tr[x][0]]<dis[tr[x][1]])swap(tr[x][0],tr[x][1]);
    dis[x]=dis[tr[x][1]]+1;
}

inline void pop(int x){
    val[x]=-1;
    f[tr[x][0]]=f[tr[x][1]]=0;
    merge(tr[x][0],tr[x][1]);
}

int main(){
    read(n);read(m);
    dis[0]=-1;
    for(int i=1;i<=n;i++)read(val[i]);
    for(int i=1;i<=m;i++){
        int ty;read(ty);
        if(ty==1){
            int x,y;
            read(x);read(y);
            if(val[x]==-1||val[y]==-1)continue;
            int fx=findfa(x),fy=findfa(y);
            if(fx==fy)continue;
            merge(fx,fy);printf("%d ",f[2]);
        }else{
            int x;read(x);
            if(val[x]==-1)puts("-1");
            else{
                int y=findfa(x);
                printf("%d\n",val[y]);
                pop(y);
            }
        }
    }
}

 

posted @ 2018-04-26 20:17  lnyzo  阅读(88)  评论(0编辑  收藏  举报