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

    题目传送门

      传送点I

      传送点II

    题目大意

      给定一个(小根)斜堆的生成方式。

    1. 如果$H$为空,或者插入的数$x$的权值小于根节点的权值,那么用$x$顶替$H$的位置,然后把$H$作为它的左子树。
    2. 否则交换$H$根的左右子树,然后递归左子树。

      给定一个斜堆,元素大小分别为$0, 1, dots, n$,问字典序最小的插入序列。

      (这篇随笔可能不太严谨。)

      考虑倒着做这么一个操作。不难发现下面这两条:

    引理1 斜堆$H$中所有非叶节点必然存在左子树。

      证明 假设存在一个非叶节点$x$不存在左子树,那么它一定只存在右子树。

      显然它不可能比它右子树中某个点$y$晚插入,因为插入$y$的时候,原来的右子树变成了左子树,之后一定存在。

      同时它也不可能比它右子树中某个点$y$之前插入,因为插入$x$的时候,$y$会在$x$的左子树中,再次插入后面的点的时候,左子树一定存在。

      因此它不存在右子树。与它是非叶节点矛盾。

      然后不难得到:

    定理2.1 当新插入的点是非叶节点的时候,它的所有父节点都有右子树,当新插入的点是叶节点的时候

    定理2.2 当新插入的点是叶节点的时候,它的父节点的所有父节点都有右子树。

      证明 设新插入的点为$x$。

    • 当$x$不是叶节点的时候,它的父节点存在同时存在左右子树。假设它的$k$级祖先存在,并同时存在左右子树,当$k + 1$级祖先存在的时候,推得$k + 1$级祖先存在右子树,所以$k + 1$级祖先同时存在左右子树。因此定理2.1得证。
    • 当$x$是叶节点的时候,它的父节点原本是叶节点或只存在左子树。剩下的一样。

      然后再讨论一下还有哪些特点

    定理3 新插入的点必定满足:

    • 在最左链上
    • 不存在右子树

      这两点都比较显然。由插入做法易证。

    定理4 一个二叉树$H$能通过斜堆车插入方式得到的充分必要条件是:

    1. 满足堆性质
    2. 要么是叶节点,要么存在左子树。

      证明  必要性 第一点显然,第二点由引理1可证。

      充分性 当点数为1的时候,显然成立。假设当点数不超过$k$时成立,考虑当点数为$k + 1$的时候。

      当根节点右子树为空,因为左子树是能够构造出来,可以先建出左子树,然后再插入根节点。

      否则我们考虑当前最后一个插入的点,由定理3可以知道它存在于当前根的左子树中。

      一个插入序列在满足根节点同时存在左右子树之后,只是交替着向两个子树中插入元素。

      假设知道了左子树和右子树的插入序列(根据归纳假设我们知道它是存在的)。 

      显然插入操作是可逆的,我们交替着撤销左右子树的插入,直到根没有同时存在两棵子树,这时候根一定不存在右子树(删完最后一个点,然后交换左右子树,所以右子树为空)。

      此时把根删掉。然后可以继续按照左子树的插入序列构造剩下的左子树。

      然后我们就倒着构造出了插入序列。

    定理5 一个点能成为最后一个插入的点的充分必要条件是:

    1. 在最左链上
    2. 不存在右子树
    3. 当是叶节点时,父节点的所有父节点存在右子树,当是非叶节点时,它的所有父节点存在右子树

      证明 必要性由以上讨论可知。

      充分性 由定理4必要性可知,每个非叶点均存在左子树并且满足堆性质。

      当它是叶节点的时候把它删掉,然后交换它所有的祖先的左右子树。它的父节点要么变成叶节点要么只存在左子树。因为它父节点的祖先均在右子树,所以左子树非空。其他点不受影响,所以所有非叶节点存在左子树。显然仍然满足堆性质。由定理4可知剩下的树能够通过斜堆的插入方法得到。

      当把这个点的左子树变为它的父节点的左子树,然后把这个点删掉后,仍然满足堆性质。类似地可以证明。

      我们仔细发现,可能成为最后一个插入的点只至多可能有2个。当最左链的叶节点的父节点满足时存在两个,否则只存在一个。

      为了使得字典序最小,我们考虑讨论第一种情况。无论发现最后一个是哪一个点,撤销它的插入后,剩下的树的形态都一样。

      所以对于其中一个的合法插入序列,交换这两个数的位置,仍然成立。

      所以一定是后插入较大的数。(不然我就交换这两个数,然后可以得到字典序更小的插入序列)。

      然后做法就变得异常简单:

    1. 找到最左链上深度最大的满足条件的点
    2. 删掉它,加入到插入序列,然后交换它的所有父节点的左右子树。

    Code

     1 /**
     2  * bzoj
     3  * Problem#1078
     4  * Accepted
     5  * Time: 4ms
     6  * Memory: 1304k
     7  */
     8 #include <iostream>
     9 #include <cstdlib>
    10 #include <cstdio>
    11 using namespace std;
    12 typedef bool boolean;
    13 
    14 const int N = 1e3 + 5;
    15 
    16 int n;
    17 int ch[N][2];
    18 int fa[N];
    19 
    20 inline void init() {
    21     scanf("%d", &n);
    22     fa[0] = -1;
    23     for (int i = 1, d; i <= n; i++) {
    24         scanf("%d", &d);
    25         if (d < 100)
    26             fa[i] = d, ch[d][0] = i;
    27         else
    28             d -= 100, fa[i] = d, ch[d][1] = i;
    29     }
    30 }
    31 
    32 int res[N];
    33 inline void solve() {
    34     int m = n;
    35     int rt = 0;
    36     while (n) {
    37         int p = rt;
    38         while (ch[p][1])
    39             p = ch[p][0];
    40         int s = ch[p][0];
    41         if (!ch[s][0])
    42             p = s;
    43         res[n--] = p;
    44 
    45         int x = fa[p];
    46         if (ch[p][0])
    47             fa[ch[p][0]] = fa[p];
    48         if (x >= 0) {
    49             ch[x][0] = ch[p][0];
    50             while (~x) {
    51                 swap(ch[x][0], ch[x][1]);
    52                 x = fa[x];
    53             }
    54         } else
    55             rt = ch[p][0];
    56     }
    57     res[0] = rt;
    58     for (int i = 0; i <= m; i++)
    59         printf("%d ", res[i]);
    60 }
    61 
    62 int main() {
    63     init();
    64     solve();
    65     return 0;
    66 }
  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/yyf0309/p/9775212.html
Copyright © 2011-2022 走看看