「BZOJ1089」[SCOI2003] 严格n元树
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 3
「样例输入3」
3 5
Sample Output
「样例输出1」
3
「样例输出2」
21
「样例输出2」
58871587162270592645034001
HINT
f[i]=f[i-1]^n+1
ans=f[d]-f[d-1]
然后加个高精度。。。
话说这个数据范围是虚的吧。。。
极限数据根本不会做。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<algorithm> #include<queue> #include<cmath> #include<map> #include<queue> #define rad 1000 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,d; struct data{int v[5005],l;}f[30]; void print(data a) { printf("%d",a.v[a.l]); for(int i=a.l-1;i;i--) printf("%03d",a.v[i]); printf("\n"); } data operator*(data a,data b) { data c; for(int i=1;i<=a.l+b.l;i++)c.v[i]=0; for(int i=1;i<=a.l;i++) for(int j=1;j<=b.l;j++) c.v[i+j-1]+=a.v[i]*b.v[j]; c.l=a.l+b.l; for(int i=1;i<=c.l;i++) if(c.v[i]>=rad) { if(i==c.l) { c.l++; c.v[i+1]=c.v[i]/rad; } else c.v[i+1]+=c.v[i]/rad; c.v[i]%=rad; } while(c.l>1&&!c.v[c.l])c.l--; return c; } data operator^(data a,int p) { data c; c.l=1;c.v[1]=1; for(int i=p;i;i>>=1,a=a*a) if(i&1)c=c*a; return c; } data operator+(data a,int p) { a.v[1]+=p; int now=1; while(a.v[now]>=rad) { a.l=max(now+1,a.l); a.v[now+1]+=a.v[now]/rad; a.v[now]%=rad; now++; a.l=max(a.l,now); } return a; } data operator-(data a,data b) { for(int i=1;i<=a.l;i++) { a.v[i]-=b.v[i]; if(a.v[i]<0) { a.v[i]+=rad; a.v[i+1]--; } } while(a.l>1&&!a.v[a.l])a.l--; return a; } int main() { n=read();d=read(); if(d==0){puts("1");return 0;} f[0].l=1;f[0].v[1]=1; for(int i=1;i<=d;i++) f[i]=(f[i-1]^n)+1; print(f[d]-f[d-1]); return 0; } |
Subscribe