Description
如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树。如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树。给出n, d,编程数出深度为d的n元树数目。
Input
仅包含两个整数n, d( 0 < n < = 32, 0 < = d < = 16)
Output
仅包含一个数,即深度为d的n元树的数目。
题解:
设
f[i]
表示深度小于等于
i
的
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=10000;
struct node
{
int v[10010],l;
}f[20];
node operator * (node a,node b)
{
node c;
c.l=a.l+b.l;
for(int i=1;i<=c.l;i++)c.v[i]=0;
for(int i=1;i<=a.l;i++)
for(int j=1;j<=b.l;j++)
c.v[i+j-1]+=a.v[i]*b.v[j];
for(int i=1;i<=c.l;i++)
if(c.v[i]>=M)
{
if(i==c.l)c.v[++c.l]=c.v[i]/M;
else c.v[i+1]+=c.v[i]/M;
c.v[i]%=M;
}
while(c.l>1&&!c.v[c.l])c.l--;
return c;
}
node operator + (node a,int b)
{
node c=a;
c.v[1]+=b;
for(int i=1;i<=c.l;i++)
if(c.v[i]>=M)
{
if(i==c.l)c.v[++c.l]=c.v[i]/M;
else c.v[i+1]+=c.v[i]/M;
c.v[i]%=M;
}
return c;
}
node operator - (node a,node b)
{
node c;
c.l=max(a.l,b.l);
for(int i=1;i<=c.l;i++)c.v[i]=0;
for(int i=1;i<=c.l;i++)
{
c.v[i]+=a.v[i]-b.v[i];
if(c.v[i]<0)
{
c.v[i]+=M;
c.v[i+1]--;
if(i+1==c.l&&c.v[i+1]==0)c.l--;
}
}
while(c.l>1&&!c.v[c.l])c.l--;
return c;
}
node p(node x,int y)
{
if(y==1)return x;
node t=p(x,y>>1),ans=t*t;
if(y&1)ans=ans*x;
return ans;
}
int main()
{
int n,d;
scanf("%d%d",&n,&d);
if(d==0){puts("1");return 0;}
f[0].v[1]=1;f[0].l=1;
for(int i=1;i<=d;i++)f[i]=p(f[i-1],n)+1;
node ans=f[d]-f[d-1];
printf("%d",ans.v[ans.l]);
for(int i=ans.l-1;i;i--)
printf("%04d",ans.v[i]);
}