zoukankan      html  css  js  c++  java
  • 【模板】左偏树

    左偏树是可合并堆的一种实现方式,可合并堆还有其他实现方式比如斜堆,然而我这种蒟蒻只会写左偏树。

    模板里的左偏树为大根堆,支持合并,查询堆顶和弹出堆顶操作,对于已经删除的位置,查询将返回-1,为了确保弹出的正常进行,模板里使用的并查集没有使用路径压缩,因此常数可能会比较大。

     1 #include<stdio.h>
     2 #define maxn 1000
     3 struct node{int ch[2],w,dist;};
     4 int n,op,ori[maxn];
     5 void swp(int &x,int &y){x^=y;y^=x;x^=y;}
     6 struct ltt
     7 {
     8     node lt[maxn];
     9     int fa[maxn]; bool sta[maxn];
    10     //int fi(int p){if(fa[p]!=p){fa[p]=fi(fa[p]);}return fa[p];}
    11     int fi(int p){return fa[p]==p?p:fi(fa[p]);}
    12     void ini()
    13     {for(int i=1;i<=n;i++) fa[i] = i,lt[i].w = ori[i];}
    14     int merge(int p,int q)
    15     {
    16         if(!p||!q) return !p ? q : p;
    17         if(lt[p].w<lt[q].w) swp(p,q);
    18         lt[p].ch[1] = merge(q,lt[p].ch[1]);
    19         if(!lt[p].ch[0]||lt[lt[p].ch[0]].dist<lt[lt[p].ch[1]].dist) swp(lt[p].ch[0],lt[p].ch[1]);
    20         lt[p].dist = !lt[p].ch[1] ? 0 : lt[lt[p].ch[1]].dist + 1;
    21         return p;
    22     }
    23     void mer(int p,int q)//合并p位置和q位置所在的左偏树
    24     {
    25         if(sta[p]||sta[q]||fi(p)==fi(q)) return;
    26         fa[fi(p)]=fa[fi(q)]=merge(fi(p),fi(q));
    27     }
    28     int top(int p)//返回p位置所在堆的堆顶,如果p位置已经被删除,返回-1
    29     {
    30         int r = fi(p); if(sta[r]) return -1;
    31         return lt[r].w;
    32     }
    33     int exmax(int p)//弹出p位置所在堆的堆顶,如果p位置已被删除,返回-1
    34     {
    35         int r = fi(p); if(sta[r]) return -1;
    36         sta[r] = true;
    37         int lc = lt[r].ch[0],rc = lt[r].ch[1];
    38         fa[lc] = fa[rc] = merge(lc,rc);
    39         return lt[r].w;
    40     }
    41 }T;
    42 int main()
    43 {
    44     scanf("%d%d",&n,&op);
    45     int i,p,q,flag;
    46     for(i=1;i<=n;i++) scanf("%d",ori+i);
    47     T.ini();
    48     for(i=1;i<=op;i++)
    49     {
    50         scanf("%d",&flag);
    51         if(flag==1)
    52         {scanf("%d%d",&p,&q);T.mer(p,q);}
    53         else if(flag==2){scanf("%d",&p);printf("%d
    ",T.exmax(p));}
    54         else{scanf("%d",&p);printf("%d
    ",T.top(p));}
    55     }
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    Java实现 LeetCode 413 等差数列划分
    Java实现 LeetCode 413 等差数列划分
    Java实现 LeetCode 412 Fizz Buzz
    简单字符设备驱动程序
    fork与vfork的区别
    进程创建函数fork()、vfork() ,以及excel()函数
    区分execl与system——应用程序中执行命令
    CMOS Sensor的调试经验分享
    嵌入式ARM-Linux开发工具下载地址合集
    嵌入式 linux 查看内存
  • 原文地址:https://www.cnblogs.com/hzs2000/p/6711113.html
Copyright © 2011-2022 走看看