BZOJ1089: [SCOI2003]严格n元树
【传送门:BZOJ1089】
简要题意:
求出深度为d的严格n元树的个数
题解:
%%%Hanks_o
f[i]表示深度小于等于i的严格n元树。
那么f[i]怎么用f[i-1]表示呢。
对于任意一个深度为i的严格n元树。
那么它的根一定有n个儿子。
这样我们就可以把它拆成一个根和n棵深度小于等于i-1的n元树了。
那么深度小于等于i-1的n元树方案已经求出来了是f[i-1]了呀。
那么在利用乘法原理得出f[i]=f[i-1]^n。
还没完,还有一棵只有根节点的树,所以f[i]还得+1
参考代码:
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> using namespace std; struct node { int a[1100],len; node() { len=0; memset(a,0,sizeof(a)); } }; node chengfa(node n1,node n2) { node no; no.len=n1.len+n2.len-1; for(int i=1;i<=n1.len;i++) for(int j=1;j<=n2.len;j++) no.a[i+j-1]+=n1.a[i]*n2.a[j]; for(int i=1;i<=no.len;i++) { no.a[i+1]+=no.a[i]/10; no.a[i]%=10; } int i=no.len; while(no.a[i+1]>0) { i++; no.a[i+1]+=no.a[i]/10; no.a[i]%=10; } no.len=i; return no; } node pow(node a,int b) { node ans; ans.a[1]=1;ans.len=1; while(b!=0) { if(b%2==1) ans=chengfa(ans,a); a=chengfa(a,a); b/=2; } return ans; } node jiafa(node n1) { node no; no=n1; no.a[1]+=1; for(int i=1;i<=no.len;i++) { no.a[i+1]+=no.a[i]/10; no.a[i]%=10; } int i=no.len; while(no.a[i+1]>0) { i++; no.a[i+1]+=no.a[i]/10; no.a[i]%=10; } no.len=i; return no; } node jianfa(node n1,node n2) { node no; no.len=n1.len; for(int i=1;i<=no.len;i++) no.a[i]=n1.a[i]-n2.a[i]; for(int i=1;i<=no.len;i++) { if(no.a[i]<0) no.a[i]+=10,no.a[i+1]--; } int i=no.len; while(i>1&&no.a[i]==0) i--; no.len=i; return no; } int main() { int n,d; scanf("%d%d",&n,&d); if(d==0){printf("1\n");return 0;} node a,b,c; a.a[1]=1;a.len=1; for(int i=1;i<=d;i++) { b=pow(a,n); if(i<d) a=jiafa(b); else c=jiafa(b); } c=jianfa(c,a); for(int i=c.len;i>=1;i--) printf("%d",c.a[i]); printf("\n"); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚