10247 - Complete Tree Labeling(递推高精度)

本文详细介绍了如何计算k-ary树的完全树中节点的不同编号方式数量,提供了输入和输出样例,并给出了实现代码。

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;
	}
}


(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值