SCOI2003 BZOJ1089 严格N元树

  个人认为这是一道比较诡异的题,首先分享题目

  如下:

  描述

如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树。如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树。例如,深度为2的严格2元树有三个,如下图:

给出n, d,编程数出深度为d的n元树数目。( 0   <   n   <   =   32,   0  < =   d  < = 16)

样例如下:

【样例输入 1 】
2 2
【样例输出 1 】
3
【样例输入 2 】
2 3
【样例输出 2 】
21
【样例输入 3 】
3 5

【样例输出 3 】
58871587162270592645034001

  看到样例3的输出我就笑了

  

  这道题也在openjudge上出过,说保证输出不超过200位的整数→_→。

  我谢谢你。

  好的接下来讲一下这道题的思路:

  我们设定最大高度为i的子树个数有

  首先,明显的,深度为0的的子树个数为1;及f[0]=1.

  其次,对于剩下的f[i]来说,f[i]=f[i-1]^n+1;及因为有n个分支,所以要先取一个f[i-1]^n,然后加上一个什么都不加的情况,所以可得到递推式。

  然后循环到b的时候我们实际上输出的是f[i]-f[i-1]为什么捏,原因很简单,因为我们算的f[i]实际上是高度为 i 的子树的前缀和,所以我们要剪掉高度为i-1的不符合题意的情况,

  贴出超来的代码→_→

 1 #include<cstdio>
 2  2 #include<cstring>
 3  3 #include<iostream>
 4  4 using namespace std;
 5  5
 6  6 const int maxn = 5000+10;
 7  7 const int rad = 1000;
 8  8
 9  9 struct Bign {  int N[maxn],len;  };
10 10 void print(Bign a) {
11 11     printf("%d",a.N[a.len-1]);
12 12     for(int i=a.len-2;i>=0;i--)
13 13         printf("%03d",a.N[i]);            //补全位数
14 14     putchar(‘\n‘);
15 15 }
16 16 Bign operator *(Bign A,Bign B) {
17 17     Bign C;
18 18     int lena=A.len,lenb=B.len;
19 19     for(int i=0;i<lena+lenb;i++) C.N[i]=0;
20 20     for(int i=0;i<lena;i++)
21 21         for(int j=0;j<lenb;j++)
22 22             C.N[i+j] += A.N[i]*B.N[j];
23 23     C.len=A.len+B.len;
24 24     for(int i=0;i<C.len;i++)
25 25         if(C.N[i]>=rad) {
26 26             if(i==C.len-1)
27 27                 C.len++ , C.N[i+1]=C.N[i]/rad;
28 28             else C.N[i+1]+=C.N[i]/rad;
29 29             C.N[i]%=rad;
30 30         }
31 31     while(C.len && !C.N[C.len-1]) C.len--;
32 32     return C;
33 33 }
34 34 Bign operator ^(Bign A,int p) {            //快速幂
35 35     Bign C;
36 36     C.len=1; C.N[0]=1;
37 37     while(p) {
38 38         if(p&1) C=C*A; A=A*A;  p>>=1;
39 39     }
40 40     return C;
41 41 }
42 42 Bign operator +(Bign A,int x) {
43 43     A.N[0]+=x;
44 44     int now=0;
45 45     while(A.N[now]>=rad) {
46 46         A.len=max(A.len,now+1);
47 47         A.N[now+1]+=A.N[now]/rad;
48 48         A.N[now]%=rad;
49 49         now++;
50 50         A.len=max(A.len,now);
51 51     }
52 52     return A;
53 53 }
54 54 Bign operator-(Bign A,Bign B) {
55 55     for(int i=0;i<A.len;i++) {
56 56         A.N[i]-=B.N[i];
57 57         if(A.N[i]<0)
58 58             A.N[i]+=rad , A.N[i+1]--;
59 59     }
60 60     while(A.len && !A.N[A.len-1]) A.len--;
61 61     return A;
62 62 }
63 63
64 64 int n,d;
65 65 Bign S[50];
66 66
67 67 int main() {
68 68     scanf("%d%d",&n,&d);
69 69     if(!d) { puts("1"); return 0; }
70 70     S[0].len=1; S[0].N[0]=1;
71 71     for(int i=1;i<=d;i++)
72 72         S[i]=(S[i-1]^n)+1;
73 73     print(S[d]-S[d-1]);
74 74     return 0;
75 75 }

  百度第一页都一个代码,及以上这段代码,然后不只一篇博客上有作者版权之类的话。。。

时间: 2024-10-13 16:30:06

SCOI2003 BZOJ1089 严格N元树的相关文章

【BZOJ】【1089】【SCOI2003】严格n元树

高精度/递推 Orz Hzwer…… 然而我想多了…… 理解以后感觉黄学长的递推好精妙啊 顺便学到了一份高精度的板子= =233 引用下题解: f[i]=f[i-1]^n+1 ans=f[d]-f[d-1] 然后加个高精度... 话说这个数据范围是虚的吧... 极限数据根本不会做.. 1 /************************************************************** 2 Problem: 1089 3 User: Tunix 4 Language:

bzoj1089严格n元树

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1089 这是一种套路:记录"深度为 i "的话,转移需要讨论许多情况:所以可以记录成"深度<=i"!!! (这种前缀和的样子得到答案也很方便,就是 f [ d ] - f [ d -1 ].) 这样的话把根节点拿出来,剩下的就是n个深度为 i - 1 的子树了. 当然,每个深度的情况里要包含"什么节点也没有"的情况,才能正确转移.所以要

[BZOJ1089][SCOI2003]严格n元树(递推+高精度)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最底层必有一个是满高度的,其他的任意. 所以直接的递推也不好想. (以下所述都是n元树) 于是可以令f[d]为深度<=d的树的个数,那么深度为d的就是f[d]-f[d-1] 对于深度<=d的又该怎么处理呢? 考虑第一层的n个点(根为0层),每个点都要底下连子树,深度为0~i-1,方案数即f[d-1]

BZOJ1089 [SCOI2003]严格n元树

又是一道奇怪的DP(?)题一个非常好的想法是:令f[i]表示深度小于等于i的n元树的总个数,于是f[i] = f[i - 1] ^ n + 1 (这是因为加了一层以后新的根的n个儿子可以随便选,再加上没有儿子的情况)但是还要写高精...还好一边A了,手感不错~ 1 /************************************************************** 2 Problem: 1089 3 User: rausen 4 Language: Pascal 5 R

bzoj 1089 [SCOI2003]严格n元树(DP+高精度)

1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1250  Solved: 621[Submit][Status][Discuss] Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严格2元树有三个,如下图: 给出n, d,编程数出深度为d的n元树数目. Inp

【BZOJ 1089】 [SCOI2003]严格n元树

1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 872  Solved: 445 [Submit][Status] Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严格2元树有三个,如下图: 给出n, d,编程数出深度为d的n元树数目. Input 仅包含两个

BZOJ 1089: [SCOI2003]严格n元树

Decription 询问深度为 \(d\) 的 \(n\) 元树个数, \(n\) 元树所有节点的孩子都有 \(n\) 个. Sol 递推+高精度. \(f[i]\) 表示深度为 \(i\) 的 \(n\) 元树个数,我这里深度是从 \([1,k+1]\) 的... 转移就是从上方添加一个节点,子节点任选然后再减去不合法的方案. \(f[i]=(\sum ^{i-1} _{j=1} f[j])^n-(\sum ^{i-2} _{j=1} f[j])^n\) Code #include<cstd

BZOJ 1089 SCOI2003 严格n元树 动态规划+高精度

题目大意:定义一棵深度为d的严格n元树为根的深度为0,最深的节点深度为d,且每一个非叶节点都有恰好n个子节点的树 给定n和d,求深度为d的严格n元树一共同拥有多少种 此题的递推部分并不难 首先我们设深度为i的严格n元树一共同拥有f[i]种 令S[i]为f[i]的前缀和 我们不难发现一棵深度为i下面的严格n元树由两部分组成:一个根节点,n棵子树.当中每棵子树的深度不超过i-1 每棵子树有S[i-1]种 一共n棵子树 于是S[i]=S[i-1]^n 嗯?是不是少了点东西?没错,另一种情况,这棵严格n

【bzoj1089】严格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 [样