标签:
10
100
0
66
第一次写左偏树,还是理解了很久,可以发现,左偏树的合并和SplitMergeTree非常相似,都是维护了堆的性质,只不过左偏树在保证堆的性质的同时维护左偏的特性,而SMTree维护的是dfs序。
左偏树合并大致为:1、按照堆的性质拼接 2、交换左右儿子以满足左偏 3、更新深度
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 1001000 bool live[MAXN]; int L[MAXN],R[MAXN],V[MAXN],D[MAXN]; int uf[MAXN]; int get_fa(int now) { return uf[now]==now ? now : uf[now]=get_fa(uf[now]); } int Merge(int x,int y) { if (!x)return y; if (!y)return x; 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; } int main() { freopen("input.txt","r",stdin); int x,y,z,n,m; scanf("%d",&n); for (int i=1;i<=n;i++)uf[i]=i,live[i]=true; for (int i=1;i<=n;i++) { scanf("%d ",V+i); D[i]=0; } scanf("%d\n",&m); char opt; for (int i=1;i<=m;i++) { scanf("%c",&opt); if (opt==‘M‘) { scanf("%d%d\n",&x,&y); if (!live[x] || !live[y])continue; if (get_fa(x)==get_fa(y))continue; uf[get_fa(x)]=uf[get_fa(y)]=Merge(get_fa(x),get_fa(y)); }else { scanf("%d\n",&x); if (!live[x]) { printf("0\n"); continue; } int t; live[t=get_fa(x)]=false; uf[t]=Merge(L[t],R[t]); uf[uf[t]]=uf[t]; printf("%d\n",V[t]); } } }
标签:
原文地址:http://www.cnblogs.com/mhy12345/p/4303169.html