zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    格式化dataGridview里数据
    XtraGrid gridview基本用法
    winForm中如何控制listView的滚动条高手请进
    WinForm 和 Windows Service 通信 消息队列
    抽象工厂模式
    C#之访问控制修饰符
    JavaScript之变量
    Android之传感器(二)持续更新
    备忘录模式
    JavaScript之构造函数初了解
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12215095.html
Copyright © 2011-2022 走看看