• 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.19

  • 相关阅读:
    style,currentStyle,getComputedStyle的区别和用法
    仿FLASH的图片轮换效果
    offset--BUG
    DIV的变高与变宽
    [SDOI2014]重建
    [SHOI2016]黑暗前的幻想乡
    「GXOI / GZOI2019」旅行者
    「GXOI / GZOI2019」旧词
    「PKUWC2018」随机算法
    「GXOI / GZOI2019」与或和
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12215095.html
Copyright © 2020-2023  润新知