hihocoder1703 第K小先序遍历

Posted 王宜鸣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hihocoder1703 第K小先序遍历相关的知识,希望对你有一定的参考价值。

思路:

给定n个节点二叉树的中序遍历,不同形态的二叉树的种类数有卡特兰数个。为了在中序序列[l, r]表示的子树上找先序序列第k小的树,首先需要从小到大枚举每个节点作根所能构成的二叉树的数目来确定树根。确定根之后,分别对左子树和右子树递归处理,具体见代码。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<int, int> pii;
 5 ll c[31], k;
 6 int a[31], n;
 7 void dfs(int l, int r, ll k)
 8 {
 9     if (l > r) return;
10     vector<pii> v;
11     for (int i = l; i <= r; i++) v.push_back(pii(a[i], i));
12     sort(v.begin(), v.end());
13     ll tmp = 0, newk = 0;
14     int i = 0;
15     while (tmp < k) 
16     { 
17         int pos = v[i++].second - l + 1;
18         newk = k - tmp;
19         tmp += c[pos - 1] * c[v.size() - pos];
20     }
21     int root = v[i - 1].second;
22     cout << a[root] << endl;
23     ll lc = c[root - l], rc = c[r - root];
24     ll lk = (newk + rc - 1) / rc;
25     ll rk = (newk % rc == 0 ? rc : newk % rc);
26     dfs(l, root - 1, lk); dfs(root + 1, r, rk);
27 }
28 int main()
29 {
30     c[0] = c[1] = 1;
31     for (int i = 2; i <= 30; i++)
32     {
33         for (int j = 0; j < i; j++)
34         {
35             c[i] += c[j] * c[i - j - 1];
36         }
37     }
38     cin >> n >> k;
39     for (int i = 1; i <= n; i++) cin >> a[i];
40     dfs(1, n, k);
41     return 0;
42 }

 

以上是关于hihocoder1703 第K小先序遍历的主要内容,如果未能解决你的问题,请参考以下文章

创建二叉树非递归完成对二叉树的先序和后序遍历并遍历输出每一层的结点数查找结点P 和结点Q的最近共同祖先

NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段

前序+中序 = 二叉树(先序中序后序层次遍历)

2023数据结构考研复习-树

2023数据结构考研复习-树

模板已知二叉树两种序列求另外一种序列--非建树