1、题意:求深度为d的n叉树的个数。
2、分析:动态规划。。设Fi表示深度小于等于i的n叉树有多少,然后可以考虑dp,新加入一个点,设这个点为根,那么这个点的每个儿子都有Fi种方案,所以是Fni,加上这个点自己本身也是一个n叉树,所以Fi=Fni+1,这就是转移方程,别忘了高精度= =
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
inline int read(){
char ch = getchar(); int x = 0, f = 1;
while(ch < ‘0‘ || ch > ‘9‘){
if(ch == ‘-‘) f = -1;
ch = getchar();
}
while(‘0‘ <= ch && ch <= ‘9‘){
x = x * 10 + ch - ‘0‘;
ch = getchar();
}
return x * f;
}
struct bign{
int a[210];
int len;
bign(){
memset(a, 0, sizeof(a));
len = 0;
}
inline bign get_bign(int rhs){
bign ret;
while(rhs){
ret.a[++ ret.len] = rhs % 10;
rhs /= 10;
}
return ret;
}
inline bool operator < (const bign& rhs) const{
if(len < rhs.len) return 1;
if(len > rhs.len) return 0;
for(int i = len; i >= 1; i --){
if(a[i] < rhs.a[i]) return 1;
if(a[i] > rhs.a[i]) return 0;
}
return 0;
}
inline bool operator > (const bign& rhs) const{
return rhs < *this;
}
inline bool operator == (const bign& rhs) const{
return !((rhs < *this) | (*this < rhs));
}
inline bool operator <= (const bign& rhs) const{
return *this == rhs || *this < rhs;
}
inline bool operator >= (const bign& rhs) const{
return *this == rhs || *this > rhs;
}
inline bool operator != (const bign& rhs) const{
return !(*this == rhs);
}
inline bign operator * (bign& rhs) const{
bign ret;
for(int i = 1; i <= len; i ++){
for(int j = 1; j <= rhs.len; j ++){
ret.a[i + j - 1] += a[i] * rhs.a[j];
ret.a[i + j] += ret.a[i + j - 1] / 10;
ret.a[i + j - 1] %= 10;
}
}
ret.len = len + rhs.len - 1;
if(ret.a[ret.len + 1]) ret.len ++;
/* puts("");
for(int i = len; i >= 1; i --) printf("%d", a[i]);
puts("");
puts("*");
rhs.print();
puts("=");
ret.print();
puts("");*/
return ret;
}
inline bign operator * (int& rhs){
bign yt = get_bign(rhs);
return *this * yt;
}
inline bign operator + (bign& rhs) const{
bign ret;
ret.len = max(len, rhs.len);
for(int i = 1; i <= ret.len; i ++){
ret.a[i] += a[i] + rhs.a[i];
ret.a[i + 1] += ret.a[i] / 10;
ret.a[i] %= 10;
}
if(ret.a[ret.len + 1]) ret.len ++;
return ret;
}
inline bign operator + (int& rhs){
bign yt = get_bign(rhs);
return *this + yt;
}
inline bign operator - (const bign& rhs) const{
bign ret;
for(int i = 1; i <= len; i ++){
ret.a[i] += a[i] - rhs.a[i];
if(ret.a[i] < 0) ret.a[i] += 10, ret.a[i + 1] --;
if(ret.a[i]) ret.len = i;
}
return ret;
}
inline bign operator - (int& rhs){
bign yt = get_bign(rhs);
return *this - yt;
}
inline bign operator / (const int& rhs) const{
bign ret;
int x = 0;
for(int i = len; i >= 1; i --){
x = x * 10 + a[i];
ret.a[i] = x / rhs;
x %= rhs;
}
ret.len = len;
while(!ret.a[ret.len] && ret.len) ret.len --;
return ret;
}
inline int operator % (const int& rhs) const{
int x = 0;
for(int i = len; i >= 1; i --){
x = x * 10 + a[i];
x %= rhs;
}
return x;
}
inline bign operator ^ (int rhs){
bign ret; ret = get_bign(1);
bign nbc = *this;
//puts("fuck");
//nbc.print();
while(rhs){
if(rhs & 1) ret = ret * nbc;
nbc = nbc * nbc;
rhs >>= 1;
}
//ret.print();
return ret;
}
inline void operator = (int x){
*this = get_bign(x);
return;
}
inline void print(){
for(int i = len; i >= 1; i --) printf("%d", a[i]);
//puts("");
}
} F[20];
int main(){
//freopen("0input.in", "r", stdin);
int n = read(), d = read();
if(d == 0){
puts("1");
return 0;
}
F[0] = 1;// F[0].print();
for(int i = 1; i <= d; i ++){
F[i] = F[i - 1] ^ n; //printf("^");F[i].print();
F[i] = F[i] + F[0]; //F[i].print();
//printf("N:%d\n", n);
}
(F[d] - F[d - 1]).print();
return 0;
}
时间: 2024-10-13 12:07:08