BZOJ1089:[SCOI2003]严格n元树(DP,高精度)
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
【样例输入2】
2 3
【样例输入3】
3 5
Sample Output
【样例输出1】
3
【样例输出2】
21
【样例输出2】
58871587162270592645034001
3
【样例输出2】
21
【样例输出2】
58871587162270592645034001
Solution
DP方程好想= =
$f[i]$表示深度不超过$i$的树的种数
$f[i]=f[i-1]^n+1$。加1是因为儿子可能为空。
最后答案为$f[d]-f[d-1]$
需要高精度……不过懒得写了直接套了个板子QAQ
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N (509) 5 using namespace std; 6 7 struct bign 8 { 9 int len, s[N]; 10 bign () 11 { 12 memset(s, 0, sizeof(s)); 13 len = 1; 14 } 15 bign (int num) { *this = num; } 16 bign (const char *num) { *this = num; } 17 bign operator = (const int num) 18 { 19 char s[N]; 20 sprintf(s, "%d", num); 21 *this = s; 22 return *this; 23 } 24 bign operator = (const char *num) 25 { 26 for(int i = 0; num[i] == '0'; num++) ; //去前导0 27 len = strlen(num); 28 for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0'; 29 return *this; 30 } 31 bign operator + (const bign &b) const //+ 32 { 33 bign c; 34 c.len = 0; 35 for(int i = 0, g = 0; g || i < max(len, b.len); i++) 36 { 37 int x = g; 38 if(i < len) x += s[i]; 39 if(i < b.len) x += b.s[i]; 40 c.s[c.len++] = x % 10; 41 g = x / 10; 42 } 43 return c; 44 } 45 bign operator += (const bign &b) 46 { 47 *this = *this + b; 48 return *this; 49 } 50 void clean() 51 { 52 while(len > 1 && !s[len-1]) len--; 53 } 54 bign operator * (const bign &b) //* 55 { 56 bign c; 57 c.len = len + b.len; 58 for(int i = 0; i < len; i++) 59 { 60 for(int j = 0; j < b.len; j++) 61 { 62 c.s[i+j] += s[i] * b.s[j]; 63 } 64 } 65 for(int i = 0; i < c.len; i++) 66 { 67 c.s[i+1] += c.s[i]/10; 68 c.s[i] %= 10; 69 } 70 c.clean(); 71 return c; 72 } 73 bign operator *= (const bign &b) 74 { 75 *this = *this * b; 76 return *this; 77 } 78 bign operator - (const bign &b) 79 { 80 bign c; 81 c.len = 0; 82 for(int i = 0, g = 0; i < len; i++) 83 { 84 int x = s[i] - g; 85 if(i < b.len) x -= b.s[i]; 86 if(x >= 0) g = 0; 87 else 88 { 89 g = 1; 90 x += 10; 91 } 92 c.s[c.len++] = x; 93 } 94 c.clean(); 95 return c; 96 } 97 bign operator -= (const bign &b) 98 { 99 *this = *this - b; 100 return *this; 101 } 102 bign operator / (const bign &b) 103 { 104 bign c, f = 0; 105 for(int i = len-1; i >= 0; i--) 106 { 107 f = f*10; 108 f.s[0] = s[i]; 109 while(f >= b) 110 { 111 f -= b; 112 c.s[i]++; 113 } 114 } 115 c.len = len; 116 c.clean(); 117 return c; 118 } 119 bign operator /= (const bign &b) 120 { 121 *this = *this / b; 122 return *this; 123 } 124 bign operator % (const bign &b) 125 { 126 bign r = *this / b; 127 r = *this - r*b; 128 return r; 129 } 130 bign operator %= (const bign &b) 131 { 132 *this = *this % b; 133 return *this; 134 } 135 bool operator < (const bign &b) 136 { 137 if(len != b.len) return len < b.len; 138 for(int i = len-1; i >= 0; i--) 139 { 140 if(s[i] != b.s[i]) return s[i] < b.s[i]; 141 } 142 return false; 143 } 144 bool operator > (const bign &b) 145 { 146 if(len != b.len) return len > b.len; 147 for(int i = len-1; i >= 0; i--) 148 { 149 if(s[i] != b.s[i]) return s[i] > b.s[i]; 150 } 151 return false; 152 } 153 bool operator == (const bign &b) 154 { 155 return !(*this > b) && !(*this < b); 156 } 157 bool operator != (const bign &b) 158 { 159 return !(*this == b); 160 } 161 bool operator <= (const bign &b) 162 { 163 return *this < b || *this == b; 164 } 165 bool operator >= (const bign &b) 166 { 167 return *this > b || *this == b; 168 } 169 string str() const 170 { 171 string res = ""; 172 for(int i = 0; i < len; i++) res = char(s[i]+'0') + res; 173 return res; 174 } 175 }; 176 177 istream& operator >> (istream &in, bign &x) 178 { 179 string s; 180 in >> s; 181 x = s.c_str(); 182 return in; 183 } 184 185 ostream& operator << (ostream &out, const bign &x) 186 { 187 out << x.str(); 188 return out; 189 } 190 191 bign Pow(bign a,int b) 192 { 193 bign ans=1; 194 for (int i=1; i<=b; ++i) 195 ans=ans*a; 196 return ans; 197 } 198 199 bign f[33],ans; 200 int n,d; 201 202 int main() 203 { 204 scanf("%d%d",&n,&d); 205 if (!d){puts("1"); return 0;} 206 f[0]=1; 207 for (int i=1; i<=d; ++i) 208 f[i]=Pow(f[i-1],n)+1; 209 cout<<f[d]-f[d-1]; 210 }