首页 > 其他分享 >【题解】CF1311E Construct the Binary Tree

【题解】CF1311E Construct the Binary Tree

时间:2022-09-18 19:56:09浏览次数:121  
标签:dep 题解 Tree st fa CF1311E 深度 -- mx

题目链接 --> Problem - E - Codeforces

题目大意

给定 \(n\) 和 \(d\),你需要构造一棵 \(n\) 个点的二叉树

满足所有点的深度之和恰好为 \(d\)。\(2≤n,d≤5000\)。

分析

  • 首先考虑深度最小的情况,也就是完全二叉树。如果 \(d\) 小于这个数,则直接输出 "NO"。

  • 否则,我们考虑对这棵树进行修改,每次让总深度 \(+1\)。

  • 首先,随便拎出来一条最深的链,此处我们选择 \(1\) 到 \(n\)。

  • 然后我们开始倒序考虑不在这条链上的所有点,每次尝试把这个点的深度 \(+1\)。

  • 只需要让这个点的父节点变为链上深度等于它的节点即可。

  • 因为在深度之和没有达到 \(d\) 的时候当前节点会一直向下走,直到不能继续,所以实际上并不会破坏二叉树的性质。

  • 而且每次我们刚好把总深度 \(+1\),所以一定能够得到所有可行的结果。

  • 如果最后还没达到 \(d\) 那就不可能构造,输出 "NO"。

Code

int n, d, mx, a[N], dep[N], fa[N];
bool st[N];

void solve() {
    cin >> n >> d;
    memset(st, 0, sizeof(st));
    mx = 0, a[0] = 1;
    for (int i = 2; i <= n; i++) {
        fa[i] = i / 2;
        dep[i] = dep[fa[i]] + 1;
        d -= dep[i];
        mx = max(mx, dep[i]);
    }

    // 考虑深度最小的情况,也就是完全二叉树。
    if (d < 0) {
        cout << "NO" << endl;
        return;
    }

    // 随便找出一条最深的链(此处1 - n),并标记在这条链上的点。
    int tmp = n;
    while (tmp) {
        a[dep[tmp]] = tmp, st[tmp] = true;
        tmp = fa[tmp];
    }

    // 倒序考虑不在这条链上的所有点。
    for (int i = n; i >= 1; i--) {
        if (st[i])  continue;

        int pre = mx;
        while (dep[fa[i]] < pre && d) {
            // 每次尝试把这个点的深度 +1   -->   让这个点的父节点变为之前选的链上深度等于它的节点
            fa[i] = a[dep[fa[i]] + 1];
            dep[i] = dep[fa[i]] + 1;
			
            // 相当于接到最深那一层
            if (dep[i] > mx)    mx++, a[mx] = i, st[i] = true;
            
            d--;
        }
    }
    if (d) {
        cout << "NO" << endl;
        return;
    }
    
    cout << "YES" << endl;
    for (re int i = 2; i <= n; i++) cout << fa[i] << " ";
    cout << endl;
    return;
}

标签:dep,题解,Tree,st,fa,CF1311E,深度,--,mx
From: https://www.cnblogs.com/Yi-Shan/p/16646681.html

相关文章

  • CSP2021-s题解
    T1廊桥分配题目链接P7913[CSP-S2021]廊桥分配\(Lemma:\)对于已经存在的廊桥集合,加入新的廊桥不会影响之前分配好的航班。证明:由于题目所给限制,若有空廊桥,则航......
  • AtCoder Regular Contest 148 C Lights Out on Tree
    挺好的一道题,简单写一下题解吧。首先有挺多很naive的结论:每个节点按两遍等于没按。熄灭所有的灯只有一种方案。其实将灯熄灭的方案无非就是从上往下dfs,如果当前灯......
  • Luogu P3674 小清新人渣的本愿 题解
    P3674小清新人渣的本愿lxl大爷的题,%%%%%以及CSPrp++!!!前言:其实是这题的名字吸引了我,毕竟人渣的本愿里的角色我觉得多多少少都沾点,哪来的小清新啊。《人渣的本愿》,又名......
  • 牛客题解 约瑟夫环
    链接:https://ac.nowcoder.com/acm/problem/22227来源:牛客网题解作者岛田小雅正统的约瑟夫环我不会,看了一眼范围直接开始乱搞了。我选择的方法是模拟,用递归函数实现(虽......
  • 2022上半年软件设计师真题解析
    选择题 ......
  • AtCoder Beginner Contest 269 (A-F)题解
    A-AnywayTakahashi这里我还是关了ll的C开了忘了关害的F多了一发罚时#include<bits/stdc++.h>usingnamespacestd;constintN=3e5+10;constintM=9982443......
  • 题解【CF1702G2 Passable Paths (hard version)】
    题目传送门。考虑建立虚树然后再上面搞树形DP。于是这道题就变成分讨题。设\(f_i\)表示\(i\)子树内的答案。若\(f_i=1\),表示\(i\)子树内的特殊点可以被一条链覆......
  • CF1718D 题解
    设\(k\)为\(a\)中的空位数量。首先咱们转化这个“相似”的条件,发现它其实是说,笛卡尔树的结构相同。那么我们把p建笛卡尔树然后把a的数往上填。如果此时有上面小于下......
  • Android安卓浏览器视频层级永远顶层问题解决方案
    在安卓手机上,使用video播放视频有个问题,video控件层级会永远在顶层,不利于视频互动H5开发,而IOS手机上不会有此问题。腾讯给出了如下解决方案:<videosrc="http://xxx.mp4......
  • AtCoder Beginner Contest 267 题解
    只会\(A\simG\)主观难度:\(A<B<C<E<D<F<G<Ex\)A-Saturday分别对周一到周五判断即可。#include<bits/stdc++.h>usingnamespacestd;inlineintread(){int......