【noi 2.6_9280】&【bzoj 1089】严格n元树(DP+高精度+重载运算符)

题意:定义一棵树的所有非叶节点都恰好有n个儿子为严格n元树。问深度为d的严格n元树数目。

解法:f[i]表示深度为<=i的严格n元树数目。f[i]-f[i-1]表示深度为i的严格n元树数目。f[i]=f[i-1]^n+1。d层的严格n元树可分解为1个根节点和n棵d-1层的严格n元树。利用乘法原理,再加上子树为空的一种情况。

P.S.同样要注意递推的思想!                           

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 struct node
 8 {
 9     int l;
10     int s[210];
11     node() {l=0;memset(s,0,sizeof(s));}
12 }f[20];
13 
14 int mmax(int x,int y) {return x>y?x:y;}
15 node operator+(node x,int y)
16 {
17     int t=1;
18     x.s[t]+=y;
19     while (x.s[t]>9) x.s[t+1]+=x.s[t]/10,x.s[t]%=10,t++;
20     return x;
21 }
22 node operator-(node x,node y)
23 {
24     node z;
25     z.l=mmax(x.l,y.l);
26     for (int i=1;i<=z.l;i++)
27     {
28       if (x.s[i]<y.s[i]) x.s[i]+=10,x.s[i+1]--;
29       z.s[i]+=x.s[i]-y.s[i];
30       if (z.s[i]>9) z.s[i+1]+=z.s[i]/10,z.s[i]%=10;
31     }
32     while (!z.s[z.l]) z.l--;
33     return z;
34 }
35 node operator*(node x,node y)
36 {
37     node z;
38     z.l=x.l+y.l-1;
39     for (int i=1;i<=x.l;i++)
40      for (int j=1;j<=y.l;j++)//不同于+!
41      {
42       z.s[i+j-1]+=x.s[i]*y.s[j];
43       if (z.s[i+j-1]>9) z.s[i+j]+=z.s[i+j-1]/10,z.s[i+j-1]%=10;
44      }
45     while (z.s[z.l+1]) z.l++;
46     return z;
47 }
48 node operator^(node x,int y)
49 {
50     node z=x,u=x;
51     y--;
52     while (y>0)
53     {
54       if (y%2) z=z*u;
55       u=u*u;//同底数幂相乘为指数的加法
56       y/=2;
57     }
58     return z;
59 }
60 void print(node x)
61 {
62     for (int i=x.l;i>=1;i--)//converse!!
63       printf("%d",x.s[i]);
64     printf("\n");
65 }
66 int main()
67 {
68     int n,d;
69     scanf("%d%d",&n,&d);
70     f[0].l=1,f[0].s[1]=1;
71     f[1].l=1,f[1].s[1]=2;
72     for (int i=2;i<=d;i++)
73       f[i]=(f[i-1]^n)+1;
74     print(f[d]-f[d-1]);//
75     return 0;
76 }

 

posted @ 2016-10-26 09:01  konjac蒟蒻  阅读(539)  评论(0编辑  收藏  举报