首页 > 其他分享 >Solution - Codeforces 1311E Construct the Binary Tree

Solution - Codeforces 1311E Construct the Binary Tree

时间:2024-07-14 15:30:56浏览次数:19  
标签:std Binary cnt le 1311E int Tree ++ 二叉树

先去考虑找一下无解条件。
首先就是有 \(d\) 关于 \(n\) 的下界 \(L\),就是弄成一颗完全二叉树的答案。
其次有 \(d\) 关于 \(n\) 的上界 \(R\),就是成一条链的样子。
首先当 \(d < L\) 或 \(R < d\) 时显然无解。

对于 \(L\le d\le R\) 又如何去判定。
能发现没有一个比较好的判定方法,于是直接考虑猜想任意 \(L\le d\le R\) 都存在解。

那么就可以考虑去通过构造来证明有解了。
因为要满足 \(L\le d\le R\) 都有解,一种想法就是先得到 \(d = L\) 的特殊解,然后去考虑调整法去调整至每次 \(+1\)。
相当于就是先弄出来完全二叉树,接下来考虑每次选一个距离为 \(x\) 的点,更换其父亲使得其距离变为 \(x + 1\)。

手玩一下能发现随便搞一搞都能有解,这里给出一种方式:
考虑找到一个有两个儿子的点,且满足两个儿子往下都是一条链。
例如有链 \(l_1, l_2\) 分别为 \(l_1 = (x, a_1, a_2), l_2 = (x, b_1, b_2, b_3)\)。
写下来考虑找到短的那一条链的尾端,\(a_2\)。
然后把 \(a_2\) 接到 \(b_2\) 后面,此时距离就从 \(2\) 变为了 \(3\),且因为 \(l_2\) 是链肯定能接。
接下来又去对于 \(l_1' = (b_2, a_2), l_2' = (b_2, b_3)\) 来做,这两条链也符合上面的条件。
能发现只有成为一条链时无法继续操作,而此时正好顶到了上界 \(R\)。

真正构造的时候并不需要模拟这个过程,因为上面只是说肯定存在解。
实际上构造时只需要维护二叉树每一层的点的个数 \(cnt_i\),能往下一层 \(+1\) 就 \(+1\)(需要满足 \(2cnt_i\ge cnt_{i + 1}\)),最后加到 \(d\) 就终止。
知道了每一层的点的个数,就不难构造这个二叉树了。

时间复杂度 \(\mathcal{O}(dn)\)。

#include<bits/stdc++.h>
inline void Main() {
   int n, d; scanf("%d%d", &n, &d);
   int lb = 0;
   for (int i = 0, n_ = n; n_; i++)
      lb += i * std::min(1 << i, n_), n_ -= std::min(1 << i, n_);
   int rb = n * (n - 1) / 2;
   if (d < lb || rb < d)
      return puts("NO"), void();
   std::vector<int> cnt(n);
   for (int i = 0, n_ = n; n_; i++)
      cnt[i] = std::min(1 << i, n_), n_ -= std::min(1 << i, n_);
   d -= lb;
   while (d) {
      bool f = 0;
      for (int i = n - 2; ~ i; i--)
         if ((cnt[i] - 1) * 2 >= (cnt[i + 1] + 1)) {
            cnt[i]--, cnt[i + 1]++, f = 1;
            break;
         }
      assert(f);
      d--;
   }
   puts("YES");
   std::vector<std::vector<int> > id(n, std::vector<int>());
   for (int i = 0, n_ = 0; i < n; i++)
      for (int j = 1; j <= cnt[i]; j++)
         id[i].push_back(++n_);
   for (int i = 1; i < n; i++)
      for (int j = 1; j <= cnt[i]; j += 2) {
         printf("%d ", id[i - 1][j >> 1]);
         if (j + 1 <= cnt[i]) printf("%d ", id[i - 1][j >> 1]);
      }
   puts("");
}
int main() {
   int T; scanf("%d", &T);
   while (T--) Main();
   return 0;
}

标签:std,Binary,cnt,le,1311E,int,Tree,++,二叉树
From: https://www.cnblogs.com/rizynvu/p/18301590

相关文章

  • TreeMap
    TreeMap由红黑树实现,可以保持元素的自然顺序,或者实现了Comparator接口的自定义顺序红黑树(英语:Red–blacktree)是一种自平衡的二叉查找树(BinarySearchTree),结构复杂,但却有着良好的性能,完成查找、插入和删除的时间复杂度均为log(n)。自然顺序默认情况下,TreeMap是根据ke......
  • 13-TreeSet和TreeMap基本介绍
    13-TreeSet和TreeMap基本介绍介绍汇总:TreeSet基本介绍TreeMap基本介绍1-TreeSet基本介绍TreeSet类用于存储一组对象,并将对象按照自然规则(实现Comparator接口的)或者指定Comparator对象的比较器进行排序。TreeSet类中的底层是TreeMap。key值不可以为null,也不......
  • extjs中treepanel例子
    :TreePanel继承自Panel,在ExtJS中使用树控件含有丰富的属性和方法实现复杂的功能。其中Ext.tree.TreeNode代表一个树节点,比较常用的属性包括text、id、icon、checked等、异步树Ext.tree.AsyncTreeNode、树加载器Ext.tree.TreeLoader。下面介绍几个extjs中treepanel例子一、TreePan......
  • D. Distance in Tree
    原题链接题解固定一个点作为树的根,易得任意一条链,都可以以某个点作为最高点,且链的两端到最高点之和为\(k\)那么不难想到遍历每个点作为最高点那么接下来就变成了在子树里选两个端点,使得到该点的距离之和为\(k\)这种无序点对统计,我们可以顺序遍历,然后对于每一个遍历到的点,计......
  • BootStrap TreeView示例
    <!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><head><title></title>......
  • Rocky Linux/Redhat8运行Calibre2022报错:Software tree is for environment VCO=aoj
    运行出现了错误:virserver.tclerror:ERROR:CurrentexecutionenvironmentisVCO=aok.SoftwaretreeisforenvironmentVCO=aoj。即calibre软件版本为aoj,但当前的环境是aok。从官网查询calibre的roadmap:http://calibre.mentorcloudservices.com/docs/Calibre_OS_Roadmap.......
  • C. Tree Infection
    https://codeforces.com/problemset/problem/1665/C题目解析很显然,树的节点感染只会在兄弟节点之间,每层独立的兄弟节点都得感染至少一个,然后让他自由扩展(时间差),那么很显然第一遍就是每层都得感染。感染的次序就是按照兄弟节点的数量降序,并且要加上1的单独节点。然后如果vis-(i......
  • 洛谷CF1342B Binary Period题解
    原题解和原题。这道题比较水。这道题分两种情况,分别为$t$由一种字符构成和由两种字符构成两种情况。$t$只有$0$或$1$。此时的$k$就是$1$,直接输出$t$就是最好的选择。$t$既有$0$又有$1$。此时的$k$为$2$,字符串由01或10构成。我们设$a_i$为字符串......
  • db B+Tree 特殊的二叉搜索树, 时间复杂度
     B+树是一种自平衡的树数据结构,常用于数据库和文件系统的实现中。它具有以下特点:多路平衡查找树:每个节点可以有多个子节点,且所有叶子节点都位于同一层,保证了树的高度相对较小,提高了查询效率。键值对存储:每个节点存储一个或多个键值对,内部节点的键用于指导搜索,而所有的......
  • [namespace hdk] Balanced_tree 整合
    代码#include<bits/stdc++.h>usingnamespacestd;namespacehdk{ namespacebalanced_tree{ constintN=2000001,inf=114514191; classsplay{ private: introot,tot; structtree{ intw; intcnt,size; intfa,son[2]; }t[N];......