Luogu P1456 Monkey King

Posted jackpei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P1456 Monkey King相关的知识,希望对你有一定的参考价值。

左偏树。

并查集维护每个元素所在左偏树的根。每次取出堆顶除二再 merge 回去。然后 merge 两个点所在的堆。

#include<iostream>
#include<cstdio>
#define R register int
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
  register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
  do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
} const int N=100010;
int n,m;
int ls[N],rs[N],vl[N],fa[N],d[N];
inline int merge(int x,int y) {
  if(!x||!y) return x+y;
  if(vl[x]<vl[y]) swap(x,y);
  rs[x]=merge(rs[x],y);
  if(d[ls[x]]<d[rs[x]]) swap(ls[x],rs[x]);
  d[x]=d[rs[x]]+1; return x;
}
inline int getf(int x) {return fa[x]==x?x:fa[x]=getf(fa[x]);}
inline void main() {
  while(~scanf("%d",&n)) {
    d[0]=-1;
    for(R i=1;i<=n;++i) 
      vl[i]=g(),fa[i]=i,ls[i]=rs[i]=d[i]=0;
    m=g();
    for(R i=1,x,y,tmp,rt,tr;i<=m;++i) {
      x=g(),y=g();
      x=getf(x),y=getf(y);
      if(x==y) {puts("-1"); continue;}
      vl[x]>>=1;
      tmp=merge(ls[x],rs[x]);
      fa[ls[x]]=fa[rs[x]]=tmp;
      ls[x]=rs[x]=d[x]=0;
      tr=merge(tmp,x);
      fa[tmp]=fa[x]=tr;
      vl[y]>>=1;
      tmp=merge(ls[y],rs[y]);
      fa[ls[y]]=fa[rs[y]]=tmp;
      ls[y]=rs[y]=d[y]=0;
      rt=merge(tmp,y);
      fa[tmp]=fa[y]=rt;
      tmp=merge(tr,rt);
      fa[tr]=fa[rt]=tmp;
      printf("%d
",vl[tmp]);
    }
  }
}
} signed main() {Luitaryi::main(); return 0;}

2020.01.18

以上是关于Luogu P1456 Monkey King的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1456 Monkey King

P1456 Monkey King

HDU 1512 Monkey King ——左偏树

「ZOJ 2334」Monkey King

Monkey King

HDU 1512 Monkey King