【SCOI 2003】 严格n元树

【题目链接】

           点击打开链接

【算法】

          f[i]表示深度小于等于i的严格n元树

          显然,一棵深度小于等于i的严格n元树,就是一个根节点,下面有n棵子树,这n棵子树都是深度小于等于i-1的严格n元树,每棵子树有f[i-1]种形态,根据乘法原理,

          可知f[i] = f[i-1] ^ n + 1

          那么最后f[d] - f[d-1]就是答案

          注意要用高精度计算

【代码】

          

#include<bits/stdc++.h>
using namespace std;
#define MAXN 35
#define MAXL 400
 
int i,n,d;
struct INT
{
		int len;
		int num[MAXL];
} ans,f[MAXN];
 
inline INT add(INT x)
{
		int i;
		reverse(x.num,x.num+x.len); 
		x.num[0]++;
		for (i = 0; i < x.len; i++)
		{
				if (x.num[i] >= 10)
				{
						x.num[i+1]++;
						x.num[i] %= 10;
				}
		}
		while (x.num[x.len]) x.len++;
		reverse(x.num,x.num+x.len);
		return x;
}
inline void multipy(INT &a,INT b)
{
		int i,j;
		static INT res;
		memset(res.num,0,sizeof(res.num));
		reverse(a.num,a.num+a.len);
		reverse(b.num,b.num+b.len);
		for (i = 0; i < a.len; i++)
		{
				for (j = 0; j < b.len; j++)
				{
						res.num[i+j] += a.num[i] * b.num[j]; 	
				}	
		}	
		res.len = a.len + b.len - 1;
		while (!res.num[res.len-1]) res.len--;
		for (i = 0; i < res.len; i++)
		{
				if (res.num[i] >= 10) 
				{
						res.num[i+1] += res.num[i] / 10;
						res.num[i] %= 10; 
				}
		}
		if (res.num[res.len]) res.len++;
		reverse(res.num,res.num+res.len);
		a = res;
}
inline INT _minus(INT a,INT b)
{
		static INT res;
		memset(res.num,0,sizeof(res.num));
		reverse(a.num,a.num+a.len);
		reverse(b.num,b.num+b.len);
		for (i = 0; i < a.len; i++)
		{
				if (a.num[i] >= b.num[i]) res.num[i] = a.num[i] - b.num[i];
				else
				{
						a.num[i+1]--;
						res.num[i] = a.num[i] + 10 - b.num[i];	
				} 
		}
		res.len = a.len;
		while (!res.num[res.len-1]) res.len--;
		reverse(res.num,res.num+res.len);
		return res;
}
inline INT power(INT a,int n)
{
		INT res;
		if (!n) return (INT){1,{1}};
		if (n == 1) return a;
		res = power(a,n>>1);
		multipy(res,res);
		if (n & 1) multipy(res,a);
		return res;	
}
inline void output(INT x)
{
		int i;
		for (i = 0; i < x.len; i++) printf("%d",x.num[i]);
		puts("");	
}

int main()
{
		
		scanf("%d%d",&n,&d);
		f[0] = (INT){1,{1}};
		for (i = 1; i <= d; i++) f[i] = add(power(f[i-1],n));
		ans = _minus(f[d],f[d-1]);
		output(ans);
	
		return 0;
}
	 

猜你喜欢

转载自blog.csdn.net/even_bao/article/details/80329378