zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    数字麦克风PDM信号采集与STM32 I2S接口应用(四)--单片机源码
    Golang SQL连接池梳理
    Ghost-无损DDL
    蛮好用的网站
    齿轮
    water
    折纸 (模拟)
    不等式(数学)
    周期串查询
    大集训模拟赛十一
  • 原文地址:https://www.cnblogs.com/wangyiming/p/8521404.html
Copyright © 2011-2022 走看看