HDU 1512 Monkey King ——左偏树
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1512 Monkey King ——左偏树相关的知识,希望对你有一定的参考价值。
【题目分析】
也是堆+并查集。
比起BZOJ 1455 来说,只是合并的方式麻烦了一点。
WA了一天才看到是多组数据。
盲人OI (~ ̄▽ ̄)~ Best OI。
代码自带大常数,比启发式合并都慢
【代码】
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <string> #include <algorithm> #include <vector> #include <iostream> #include <queue> using namespace std; #define maxn 100005 int read() { int x=0,f=1; char ch=getchar(); while (ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} while (ch>=‘0‘&&ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} return x*f; } int f[maxn],l[maxn],r[maxn],n,m,d[maxn]; int v[maxn]; int gf(int k) { if (f[k]==k) return k; else return f[k]=gf(f[k]); } 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; } int main() { while (scanf("%d",&n)!=EOF) { memset(l,0,sizeof l); memset(r,0,sizeof r); for (int i=1;i<=n;++i) v[i]=read(),f[i]=i; m=read(); for (int i=1;i<=m;++i) { int x=read(),y=read(); int fx=gf(x),fy=gf(y); if (fx==fy) { printf("-1\n"); continue; } else { int tmp1=merge(l[fx],r[fx]); int tmp2=merge(l[fy],r[fy]); v[fx]/=2; v[fy]/=2; l[fx]=r[fx]=l[fy]=r[fy]=0; tmp1=merge(fx,tmp1); tmp2=merge(fy,tmp2); f[fx]=f[tmp1]=tmp1; f[fy]=f[tmp2]=tmp2; int tmp=merge(tmp1,tmp2); f[fx]=f[fy]=tmp; if (tmp1) f[tmp1]=tmp; if (tmp2) f[tmp2]=tmp; printf("%d\n",v[tmp]); } } } }
以上是关于HDU 1512 Monkey King ——左偏树的主要内容,如果未能解决你的问题,请参考以下文章