1089: [SCOI2003]严格n元树
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1959 Solved: 991
[Submit][Status][Discuss]
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
令f[i]表示深度<=i的树有多少种
考虑深度<=i的树由n个深度<=i-1的接到根上,发现现在只有一个根的被接上了,再加回来
所以f[i]=f[i-1]^n+1
之后就高精度搞 泪
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=5010,rad=1000;
struct bint
{
int a[N];
friend bint operator *(bint x,bint y)
{
bint c;
c.init();
c.a[0]=x.a[0]+y.a[0]+3;
for(int i=1;i<=x.a[0];++i)
for(int j=1;j<=y.a[0];++j)
c.a[i+j-1]+=x.a[i]*y.a[j];
for(int i=1;i<=c.a[0];++i)
if(c.a[i]>=rad)
{
c.a[i+1]+=c.a[i]/rad;
c.a[i]%=rad;
if(c.a[0]==i)c.a[0]++;
}
while(!c.a[c.a[0]]&&c.a[0]>1)c.a[0]--;
return c;
}
friend bint operator ^(bint x,int y)
{
bint res;
res.init();
res.a[1]=1;
while(y)
{
if(y&1)res=res*x;
x=x*x;
y>>=1;
}
return res;
}
friend bint operator +(bint x,int y)
{
x.a[1]+=y;
for(int i=1;i<=x.a[0];++i)
if(x.a[0]>=rad)
{
x.a[i+1]+=x.a[i]/rad;
x.a[i]%=rad;
if(x.a[0]==i)x.a[0]++;
}
while(x.a[0]>1&&!x.a[x.a[0]])x.a[0]--;
return x;
}
friend bint operator -(bint x,bint y)
{
for(int i=1;i<=x.a[0];++i)
{
x.a[i]-=y.a[i];
if(x.a[i]<0)
{
x.a[i]+=rad;
x.a[i+1]--;
}
}
while(x.a[0]>1&&!x.a[x.a[0]])x.a[0]--;
return x;
}
friend void lala(bint x)
{
printf("%d",x.a[x.a[0]]);
for(int i=x.a[0]-1;i;i--)printf("%03d",x.a[i]);
puts("");
}
void init()
{
memset(a,0,sizeof(a));
a[0]=1;
}
}f[20];
int main()
{
int n=read(),D=read();
for(int i=1;i<=D;++i)f[i].init();
f[1].a[1]=1;
for(int i=2;i<=D+1;++i)f[i]=(f[i-1]^n)+1;
if(D)lala(f[D+1]-f[D]);
else puts("1");
return 0;
}
/*
2 2
3
2 3
21
3 5
58871587162270592645034001
*/