1. 程式人生 > >hihocoder1703 第K小先序遍歷

hihocoder1703 第K小先序遍歷

second type 先序 def vector 枚舉 hihocode 需要 esp

思路:

給定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小先序遍歷