zoukankan      html  css  js  c++  java
  • BZOJ1078 [SCOI2008]斜堆

    一个巨坑总算是填上了。。。

    从十一开始调直到今天才过掉,已经交了上50次了。。。在无数RE后才发现,本地评测真是啃爹啊啊啊啊!!!

    Mato大神说的好:"其实是一个超级大水题"。。。我是蒟蒻又被虐了。。。

    对于斜堆插入的最后一个节点,可以推出两点性质:

    (1)它一定是一个树中的极左节点

    (2)它肯定没有右子树

    然后又可以发现,所有斜堆中的点,如果他没有左子树,也不会有右子树。(就是非叶子必有左子树,废话吧。。。)

    然后Mato balabala说了一堆。。。(看不懂。。。)得到最终结论:

    最后插入的节点X,必然是满足(1)(2),且深度最小,除非他的左子树只有一个节点。(为了满足插入队列最小)

    所以做法是:

    (1)按照上面的结论找到当前插入的节点

    (2)删掉该点

    (3)把它的祖先的左右子树都交换了

    就做完了

     1 /**************************************************************
     2     Problem: 1078
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:0 ms
     7     Memory:812 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12  
    13 using namespace std;
    14  
    15 struct heap{
    16     int lson, rson, fa;
    17     heap(){
    18         lson = rson = fa = -1;
    19     }
    20 }h[300];
    21  
    22 int n, X, ans[300], root;
    23  
    24 void work(){
    25     int cnt = n + 1, p, fa, son;
    26     bool flag;
    27     while (cnt){
    28         flag = 0;
    29         p = root;
    30         while (h[p].rson != -1) p = h[p].lson;
    31         son = h[p].lson;
    32         if (son != -1 && h[son].lson == - 1 && h[son].rson == -1) 
    33             p = son;
    34         ans[cnt--] = p;
    35          
    36         fa = h[p].fa, son = h[p].lson;
    37         if (p == root){
    38             root = son, flag = 1;
    39             h[son].fa = -1;
    40         }
    41         else if (son != -1)
    42             h[fa].lson = son, h[son].fa = fa;
    43         else h[fa].lson = -1;
    44         if (!flag)
    45         while (p != root){
    46             p = h[p].fa;
    47             swap(h[p].lson, h[p].rson);
    48         }
    49     }
    50 }
    51  
    52 int main(){
    53     scanf("%d", &n);
    54     for (int i = 1; i <= n; ++i){
    55         scanf("%d", &X);
    56         if (X >= 100) h[X - 100].rson = i, h[i].fa = X - 100;
    57         else h[X].lson = i, h[i].fa = X;
    58     }
    59      
    60     root = 0;
    61     work();
    62     for (int i = 1; i <= n + 1; ++i)
    63         printf("%d ", ans[i]);
    64     printf("
    ");
    65     return 0;
    66 }
    View Code

    (p.s. 我是fa = -1的时候访问了h[fa],结果RE不止,调到现在才搞明白。。。真是太弱了。。。)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    解决Java版CKFinder无法显示缩略图问题
    python视频教程大全
    关于Linux vi命令 vi命令一览表
    Python快速教程
    Linux的概念与体系
    每天一个linux命令目录
    每天一个linux命令(31): /etc/group文件详解
    每天一个linux命令(30): chown命令
    每天一个linux命令(29):chgrp命令
    十大Material Design开源项目
  • 原文地址:https://www.cnblogs.com/rausen/p/4033308.html
Copyright © 2011-2022 走看看