您的位置:首页 > 其它

BZOJ 1089: [SCOI2003]严格n元树 递推 高精度

2017-11-02 16:48 363 查看

1089: [SCOI2003]严格n元树

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 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

Sample Output

【样例输出1】

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
;

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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: