10247 - Complete Tree Labeling(递推高精度)
Problem B
Complete Tree Labeling!
Input: standard input
Output: standard output
Time Limit: 45 seconds
Memory Limit: 32 MB
A complete k-ary tree is a k-ary tree in which all leaves have same depth and all internal nodes have degree k. This k is also known as the branching factor of a tree. It is very easy to determine the number of nodes of such a tree. Given the depth and branching factor of such a tree, you will have to determine in how many different ways you can number the nodes of the tree so that the label of each node is less that that of its descendants. You should assume that for numbering a tree with N nodes you have the (1, 2, 3, N-1, N) labels available.
Input
The input file will contain several lines of input. Each line will contain two integers k and d. Here k is the branching factor of the complete k-arytree and d is the depth of the complete k-ary tree (k>0, d>0, k*d<=21).
Output
For each line of input, produce one line of output containing a round number, which is the number of ways the k-ary tree can be labeled, maintaining the constraints described above.
Sample Input:
2 2
10 1
Sample Output:
80
3628800
题意:k叉d层树最多组成几种搜索树。
思路:参考http://www.2cto.com/kf/201310/251470.html
代码:
#include <stdio.h>
#include <string.h>
#include <math.h> #define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b) const int MAXSIZE = 10000; struct bign {
int s[MAXSIZE];
bign () {memset(s, 0, sizeof(s));}
bign (int number) {*this = number;}
bign (const char* number) {*this = number;} void put();
bign mul(int d);
void del();
void init() { memset(s, 0, sizeof(s)); } bign operator = (char *num);
bign operator = (int num); bool operator < (const bign& b) const;
bool operator > (const bign& b) const { return b < *this; }
bool operator <= (const bign& b) const { return !(b < *this); }
bool operator >= (const bign& b) const { return !(*this < b); }
bool operator != (const bign& b) const { return b < *this || *this < b;}
bool operator == (const bign& b) const { return !(b != *this); } bign operator + (const bign& c);
bign operator * (const bign& c);
bign operator - (const bign& c);
int operator / (const bign& c);
bign operator / (int k);
bign operator % (const bign &c);
int operator % (int k);
void operator ++ ();
bool operator -- ();
}; bign f[25][25];
int node[25][25];
int n, m; bign c(int n, int m) {
bign ans = 1;
m = min(m, n - m);
for (int i = 0; i < m; i ++) {
bign save = (n - i);
ans = ans * save / (i + 1);
}
return ans;
} void init() {
int i, j, k;
for (i = 1; i <= 21; i ++) {
f[i][0] = 1; node[i][0] = 1;
for (j = 1; j <= 21 / i; j ++) {
f[i][j] = 1;
for (k = 0; k < i; k ++) {
node[i][j] = node[i][j - 1] * i + 1;
f[i][j] = f[i][j] * c(node[i][j] - 1 - k * node[i][j - 1], node[i][j - 1]) * f[i][j - 1];
}
}
}
} int main() {
init();
while (~scanf("%d%d", &n, &m)) {
f[n][m].put();
printf("\n");
}
return 0;
} bign bign::operator = (char *num) {
init();
s[0] = strlen(num);
for (int i = 1; i <= s[0]; i++)
s[i] = num[s[0] - i] - '0';
return *this;
} bign bign::operator = (int num) {
char str[MAXSIZE];
sprintf(str, "%d", num);
return *this = str;
} bool bign::operator < (const bign& b) const {
if (s[0] != b.s[0])
return s[0] < b.s[0];
for (int i = s[0]; i; i--)
if (s[i] != b.s[i])
return s[i] < b.s[i];
return false;
} bign bign::operator + (const bign& c) {
int sum = 0;
bign ans;
ans.s[0] = max(s[0], c.s[0]); for (int i = 1; i <= ans.s[0]; i++) {
if (i <= s[0]) sum += s[i];
if (i <= c.s[0]) sum += c.s[i];
ans.s[i] = sum % 10;
sum /= 10;
}
return ans;
} bign bign::operator * (const bign& c) {
bign ans;
ans.s[0] = 0; for (int i = 1; i <= c.s[0]; i++){
int g = 0; for (int j = 1; j <= s[0]; j++){
int x = s[j] * c.s[i] + g + ans.s[i + j - 1];
ans.s[i + j - 1] = x % 10;
g = x / 10;
}
int t = i + s[0] - 1; while (g){
++t;
g += ans.s[t];
ans.s[t] = g % 10;
g = g / 10;
} ans.s[0] = max(ans.s[0], t);
}
ans.del();
return ans;
} bign bign::operator - (const bign& c) {
bign ans = *this;
int i;
for (i = 1; i <= c.s[0]; i++) {
if (ans.s[i] < c.s[i]) {
ans.s[i] += 10;
ans.s[i + 1]--;;
}
ans.s[i] -= c.s[i];
} for (i = 1; i <= ans.s[0]; i++) {
if (ans.s[i] < 0) {
ans.s[i] += 10;
ans.s[i + 1]--;
}
} ans.del();
return ans;
} int bign::operator / (const bign& c) {
int ans = 0;
bign d = *this;
while (d >= c) {
d = d - c;
ans++;
}
return ans;
} bign bign::operator / (int k) {
bign ans;
ans.s[0] = s[0];
int num = 0;
for (int i = s[0]; i; i--) {
num = num * 10 + s[i];
ans.s[i] = num / k;
num = num % k;
}
ans.del();
return ans;
} int bign:: operator % (int k){
int sum = 0;
for (int i = s[0]; i; i--){
sum = sum * 10 + s[i];
sum = sum % k;
}
return sum;
} bign bign::operator % (const bign &c) {
bign now = *this;
while (now >= c) {
now = now - c;
now.del();
}
return now;
} void bign::operator ++ () {
s[1]++;
for (int i = 1; s[i] == 10; i++) {
s[i] = 0;
s[i + 1]++;
s[0] = max(s[0], i + 1);
}
} bool bign::operator -- () {
del();
if (s[0] == 1 && s[1] == 0) return false; int i;
for (i = 1; s[i] == 0; i++)
s[i] = 9;
s[i]--;
del();
return true;
} void bign::put() {
if (s[0] == 0)
printf("0");
else
for (int i = s[0]; i; i--)
printf("%d", s[i]);
} bign bign::mul(int d) {
s[0] += d;
int i;
for (i = s[0]; i > d; i--)
s[i] = s[i - d];
for (i = d; i; i--)
s[i] = 0;
return *this;
} void bign::del() {
while (s[s[0]] == 0) {
s[0]--;
if (s[0] == 0) break;
}
}
10247 - Complete Tree Labeling(递推高精度)的更多相关文章
- PKU 2506 Tiling(递推+高精度||string应用)
题目大意:原题链接有2×1和2×2两种规格的地板,现要拼2×n的形状,共有多少种情况,首先要做这道题目要先对递推有一定的了解.解题思路:1.假设我们已经铺好了2×(n-1)的情形,则要铺到2×n则只能 ...
- 递推+高精度+找规律 UVA 10254 The Priest Mathematician
题目传送门 /* 题意:汉诺塔问题变形,多了第四个盘子可以放前k个塔,然后n-k个是经典的汉诺塔问题,问最少操作次数 递推+高精度+找规律:f[k]表示前k放在第四个盘子,g[n-k]表示经典三个盘子 ...
- [luogu]P1066 2^k进制数[数学][递推][高精度]
[luogu]P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻 ...
- [BZOJ1089][SCOI2003]严格n元树(递推+高精度)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最 ...
- 【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
1002: [FJOI2007]轮状病毒 Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同 ...
- BZOJ 1002 FJOI2007 轮状病毒 递推+高精度
题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring& ...
- 递推 + 高精度 --- Tiling
Tiling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7264 Accepted: 3528 Descriptio ...
- 【BZOJ】1089: [SCOI2003]严格n元树(递推+高精度/fft)
http://www.lydsy.com/JudgeOnline/problem.php?id=1089 题意:求深度为d的n元树数目.(0<n<=32, 0<=d<=16) ...
- 递推+高精度 UVA 10497 Sweet Child Makes Trouble(可爱的孩子惹麻烦)
题目链接 题意: n个物品全部乱序排列(都不在原来的位置)的方案数. 思路: dp[i]表示i个物品都乱序排序的方案数,所以状态转移方程.考虑i-1个物品乱序,放入第i个物品一定要和i-1个的其中一个 ...
随机推荐
- android加载更多的图片
这是昨天改进后的,我测试了下,可以加载图片到5万张,估计5万以上也是没问题的,我只试到5万,其实也没必要这么高,现实中1000左右就差不多了,不过我的应用到100就差不多了, package com. ...
- 网易云课堂_C语言程序设计进阶_第四周:ACL图形库
创建ACLLib程序 #include"acllib.h" #include<stdio.h> int Setup1() { initWindow(, );//初始化窗 ...
- collection系列用法-namedtuple()
namedtuple() 参考文章地址:http://www.cnblogs.com/herbert/p/3468294.html namedtuple是继承自tuple的子类.namedtuple和 ...
- iOS实现文件上传功能模块
iOS实现文件上传功能,首先要知道的是,上传到服务器的数据格式,一般采用HTTP文件上传协议.如下图 如图所示,只要设置好了HTTP的协议格式,就可以实现文件上传功能. 代码如下: //图片上传模块 ...
- Rikka with Chess(规律)
Rikka with Chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- Ubuntu创建快捷方式
正常安装putty不成功:sudo apt-get install putty 总是报网络方面的错,我只好从官网下载源码自己编译.还是很容易的,找到unix目录,然后执行:make -f Makefi ...
- 列表的实现-----数据结构与算法JavaScript描述 第三章
实现一个列表 script var booklist = new List(); booklist.append('jsbook'); booklist.append('cssbook'); book ...
- 软件介绍:搜索工具 Listary
如今的互联网时代,搜索的重要性我想大家都是认可的.网上的知识浩如烟海,而搜索引擎是通向这些知识的入口.谷歌.百度等搜索引擎给我们带来了极大的便利,也无怪他们成长为如今的互联网巨头. 然而储存在个人硬件 ...
- Csharp多态的实现(虚方法)
1.什么是抽象类 1.1虚方法是用virtual修饰,在子类中用override进行重写 1.2虚方法是一个方法,放在类里面(可以再下面的代码中看到) 1.3虚方法可以 重写,也可以不重写(这个可以再 ...
- Oracle包的概念
转自:http://www.cnblogs.com/lovemoon714/archive/2012/02/29/2373695.html 1.为什么要使用包? 答: 在一个大型项目中,可 ...