【bzoj1089】严格n元树
Description
如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树。如果该树中最底层的节点深度为d
(根的深度为0),那么我们称它为一棵深度为d的严格n元树。例如,深度为2的严格2元树有三个,如下图:
给出n, d,编程数出深度为d的n元树数目。
Input
仅包含两个整数n, d( 0 < n < = 32, 0 < = d < = 16)
Output
仅包含一个数,即深度为d的n元树的数目。
Sample Input
【样例输入1】
2 2
【样例输入2】
2 3
【样例输入3】
3 5
2 2
【样例输入2】
2 3
【样例输入3】
3 5
Sample Output
【样例输出1】
3
【样例输出2】
21
【样例输出2】
58871587162270592645034001
3
【样例输出2】
21
【样例输出2】
58871587162270592645034001
Solution
令s[i]为深度不超过i的n元树的数量
显然的s[i]=s[i-1]^n+1
加上高精度即可
#include<stdio.h> #include<stdlib.h> #include<iostream> #include<string> #include<string.h> #include<algorithm> #include<math.h> #include<queue> #include<map> #include<vector> #include<set> #define il inline #define re register using namespace std; int n,d; struct bignum{int len,s[301]; } f[101]; il bignum operator*(bignum a,bignum b){ bignum c; memset(c.s,false,sizeof(c.s)); c.len=a.len+b.len-1; for(int i=1;i<=a.len;i++) for(int j=1;j<=b.len;j++){ c.s[i+j-1]+=a.s[i]*b.s[j]; c.s[i+j]+=c.s[i+j-1]/10000; c.s[i+j-1]%=10000; } if(c.s[c.len+1]>0) c.len++; return c; } il void operator++(bignum &a){ a.s[1]++; for(int i=1;i<=a.len;i++){ a.s[i+1]+=a.s[i]/10000; a.s[i]%=10000; } if(a.s[a.len+1]>0) a.len++; } il bignum operator-(bignum a,bignum b){ bignum c; memset(c.s,false,sizeof(c.s)); c.len=a.len; for(int i=1;i<=c.len;i++){ c.s[i]+=a.s[i]-b.s[i]; if(c.s[i]<0) c.s[i+1]--; c.s[i]=(c.s[i]+10000)%10000; } return c; } il void print(bignum a){ printf("%d",a.s[a.len]); for(int i=a.len-1;i>0;i--) printf("%04d",a.s[i]); printf("\n"); } int main(){ scanf("%d%d",&d,&n); if(d==0){ cout<<"1";return 0; } f[0].len=1;f[0].s[1]=1; for(int i=1;i<=n;i++){ f[i].len=1;f[i].s[1]=1; for(int j=1;j<=d;j++){ f[i]=f[i]*f[i-1]; // print(f[i]); } ++f[i]; } print(f[n]-f[n-1]); return 0; }
蜉蝣渴望着飞翔,尽管黄昏将至