【题目链接】
【算法】
f[i]表示深度小于等于i的严格n元树
显然,一棵深度小于等于i的严格n元树,就是一个根节点,下面有n棵子树,这n棵子树都是深度小于等于i-1的严格n元树,每棵子树有f[i-1]种形态,根据乘法原理,
可知f[i] = f[i-1] ^ n + 1
那么最后f[d] - f[d-1]就是答案
注意要用高精度计算
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 35 #define MAXL 400 int i,n,d; struct INT { int len; int num[MAXL]; } ans,f[MAXN]; inline INT add(INT x) { int i; reverse(x.num,x.num+x.len); x.num[0]++; for (i = 0; i < x.len; i++) { if (x.num[i] >= 10) { x.num[i+1]++; x.num[i] %= 10; } } while (x.num[x.len]) x.len++; reverse(x.num,x.num+x.len); return x; } inline void multipy(INT &a,INT b) { int i,j; static INT res; memset(res.num,0,sizeof(res.num)); reverse(a.num,a.num+a.len); reverse(b.num,b.num+b.len); for (i = 0; i < a.len; i++) { for (j = 0; j < b.len; j++) { res.num[i+j] += a.num[i] * b.num[j]; } } res.len = a.len + b.len - 1; while (!res.num[res.len-1]) res.len--; for (i = 0; i < res.len; i++) { if (res.num[i] >= 10) { res.num[i+1] += res.num[i] / 10; res.num[i] %= 10; } } if (res.num[res.len]) res.len++; reverse(res.num,res.num+res.len); a = res; } inline INT _minus(INT a,INT b) { static INT res; memset(res.num,0,sizeof(res.num)); reverse(a.num,a.num+a.len); reverse(b.num,b.num+b.len); for (i = 0; i < a.len; i++) { if (a.num[i] >= b.num[i]) res.num[i] = a.num[i] - b.num[i]; else { a.num[i+1]--; res.num[i] = a.num[i] + 10 - b.num[i]; } } res.len = a.len; while (!res.num[res.len-1]) res.len--; reverse(res.num,res.num+res.len); return res; } inline INT power(INT a,int n) { INT res; if (!n) return (INT){1,{1}}; if (n == 1) return a; res = power(a,n>>1); multipy(res,res); if (n & 1) multipy(res,a); return res; } inline void output(INT x) { int i; for (i = 0; i < x.len; i++) printf("%d",x.num[i]); puts(""); } int main() { scanf("%d%d",&n,&d); f[0] = (INT){1,{1}}; for (i = 1; i <= d; i++) f[i] = add(power(f[i-1],n)); ans = _minus(f[d],f[d-1]); output(ans); return 0; }