Let f(k, d) denote the number of labelings of the k-ary tree of depth d. Moreover, let n(k, d) denote the number of nodes of the tree. The tree contains k subtrees, each contains n(k, d-1) nodes. There are totally (n(k, d) - 1)! / (n(k, d-1)!)^k ways to partition the n(k, d) - 1 labels into k different subsets, each have the same size of n(k, d-1), therefore we can draw this recurrence:
f(k, d) = (n(k, d) - 1)! / (n(k, d-1)!)^k * f(k, d-1)
with base cases of
f(k, 0) = 1
Code:
- /***************************************************************************
- * Copyright (C) 2008 by Liu Kaipeng *
- * LiuKaipeng at gmail dot com *
- ***************************************************************************/
- /* @JUDGE_ID 00000 10247 C++ "Complete Tree Labeling" */
- #include <algorithm>
- #include <cstdio>
- #include <cstring>
- #include <deque>
- #include <fstream>
- #include <iostream>
- #include <list>
- #include <map>
- #include <queue>
- #include <set>
- #include <stack>
- #include <string>
- #include <vector>
- #include "big_unsigned.hpp"
- using namespace std;
- /*
- * Let f(k, d) denote the number of labelings of the k-ary tree of depth d.
- * Moreover, let n(k, d) denote the number of nodes of the tree. The tree
- * contains k subtrees, each contains n(k, d-1) nodes. There are totally
- * (n(k, d) - 1)! / (n(k, d-1)!)^k ways to partition the n(k, d) - 1 labels
- * into k different subsets, each have the same size of n(k, d-1), therefore
- * we can draw this recurrence:
- * f(k, d) = (n(k, d) - 1)! / (n(k, d-1)!)^k * f(k, d-1)
- * with base cases of
- * f(k, 0) = 1
- */
- big_unsigned numbers[22][22];
- void gen_numbers()
- {
- unsigned powers[22][22];
- for (int k = 1; k <= 21; ++k) {
- powers[k][0] = 1;
- for (int d = 1; d * k <= 21; ++d)
- powers[k][d] = powers[k][d-1] * k;
- }
- unsigned nodes[22][22];
- unsigned max_fac = 0;
- for (int k = 1; k <= 21; ++k) {
- nodes[k][0] = 1;
- for (int d = 1; d * k <= 21; ++d)
- if ((nodes[k][d] = nodes[k][d-1] + powers[k][d]) > max_fac)
- max_fac = nodes[k][d];
- }
- vector<big_unsigned> facs(max_fac);
- facs[0] = 1;
- for (unsigned i = 1; i < max_fac; ++i)
- facs[i] = facs[i-1] * i;
- for (int k = 1; k <= 21; ++k) {
- numbers[k][0] = 1;
- for (int d = 1; d * k <= 21; ++d) {
- numbers[k][d] = numbers[k][d-1];
- for (int i = 1; i != k; ++i) numbers[k][d] *= numbers[k][d-1];
- numbers[k][d] *= facs[nodes[k][d]-1];
- for (int i = 0; i < k; ++i) numbers[k][d] /= facs[nodes[k][d-1]];
- }
- }
- }
- int main(int argc, char *argv[])
- {
- #ifndef ONLINE_JUDGE
- freopen((string(argv[0]) + ".in").c_str(), "r", stdin);
- freopen((string(argv[0]) + ".out").c_str(), "w", stdout);
- #endif
- gen_numbers();
- for (int k, d; cin >> k >> d; ) cout << numbers[k][d] << '/n';
- return 0;
- }