BZOJ 1089: [SCOI2003]严格n元树【数学题】
1089: [SCOI2003]严格n元树
Time Limit: 1 Sec Memory Limit: 162 MB
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]=f[i−1]N+1 (多推几个就可以了)
最后答案就是f[d]−f[d−1] 。
然后我们看第三个样例,恩~,要高精度。。。
不mod会死啊!!!
QAQ
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int tt=10000;
struct xcw{
int len,a[205];
int &operator [](int x){return a[x];}
xcw(){len=0;memset(a,0,sizeof(a));}
xcw(int x){memset(a,0,sizeof(a));a[len=1]=x;}
xcw operator *(const xcw b) const{
xcw c;
c.len=len+b.len-1;
for(int i=1;i<=len;i++)
for(int j=1;j<=b.len;j++){
c.a[i+j-1]+=a[i]*b.a[j];
c.a[i+j]+=c.a[i+j-1]/tt;
c.a[i+j-1]%=tt;
}
if(c.a[c.len+1]) c.len++;
return c;
}
xcw operator +(const xcw b) const{
xcw c;
c.len=max(len,b.len);
for(int i=1;i<=c.len;i++){
c.a[i]+=a[i]+b.a[i];
c.a[i+1]+=c.a[i]/tt;
c.a[i]%=tt;
}
if(c.a[c.len+1]) c.len++;
return c;
}
xcw operator -(const xcw b) const{
xcw c;
c.len=max(len,b.len);
for(int i=1;i<=c.len;i++){
c.a[i]+=a[i]-b.a[i]+tt;
c.a[i+1]+=c.a[i]/tt-1;
c.a[i]%=tt;
}
while(!c.a[c.len]&&c.len>1) c.len--;
return c;
}
void print(){
printf("%d",a[len]);
for(int i=len-1;i;i--) printf("%04d",a[i]);
printf("\n");
}
}f[20],ans,One;
int n,d;
xcw qsm(xcw x){
xcw sum=1;
for(int i=1;i<=n;i++) sum=sum*x;
return sum;
}
int main(){
scanf("%d%d",&n,&d);
f[0]=1;
for(int i=1;i<=d;i++) f[i]=qsm(f[i-1])+1;
ans=f[d]-f[d-1];
ans.print();
return 0;
}