我们知道包含 N 个元素的堆可以看成是一棵包含 N 个节点的完全二叉树。
每个节点有一个权值。对于小根堆来说,父节点的权值一定小于其子节点的权值。
假设 N 个节点的权值分别是 1~N,你能求出一共有多少种不同的小根堆吗?
例如对于 N=4 有如下 3 种:
1
/
2 3
/
4
1
/
3 2
/
4
1
/
2 4
/
3
由于数量可能超过整型范围,你只需要输出结果除以 1000000009 的余数。
【输入格式】 一个整数 N。
对于 40% 的数据,1 <= N <= 1000
对于 70% 的数据,1 <= N <= 10000
对于 100% 的数据,1 <= N <= 100000
【输出格式】 一个整数表示答案。
【输入样例】 4
【输出样例】 3
资源约定: 峰值内存消耗(含虚拟机) < 256M CPU 消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 不要使用 package 语句。不要使用 jdk1.7 及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
1 |
<span class="token macro property">#<span class="token directive keyword">include</span><span class="token string"><bits/stdc++.h></span></span> using namespace std<span class="token punctuation">;</span> <span class="token keyword">typedef</span> <span class="token keyword">long</span> <span class="token keyword">long</span> ll<span class="token punctuation">;</span> <span class="token keyword">const</span> <span class="token keyword">int</span> maxn <span class="token operator">=</span> <span class="token number">100000</span><span class="token punctuation">;</span> ll s<span class="token punctuation">[</span>maxn<span class="token operator">+</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">,</span>dp<span class="token punctuation">[</span>maxn<span class="token operator">+</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">,</span>inv<span class="token punctuation">[</span>maxn<span class="token operator">+</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">,</span>f<span class="token punctuation">[</span>maxn<span class="token operator">+</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span> ll n<span class="token punctuation">;</span> ll mod <span class="token operator">=</span> <span class="token number">1000000009</span><span class="token punctuation">;</span> ll <span class="token function">qPow</span><span class="token punctuation">(</span>ll a<span class="token punctuation">,</span>ll b<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> ll ans <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">while</span><span class="token punctuation">(</span>b<span class="token operator">!=</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token keyword">if</span><span class="token punctuation">(</span>b<span class="token operator">&</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> ans <span class="token operator">=</span> ans<span class="token operator">*</span>a<span class="token operator">%</span>mod<span class="token punctuation">;</span> <span class="token punctuation">}</span> a <span class="token operator">=</span> a<span class="token operator">*</span>a<span class="token operator">%</span>mod<span class="token punctuation">;</span> b <span class="token operator">>>=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> ans<span class="token operator">%</span>mod<span class="token punctuation">;</span> <span class="token punctuation">}</span> ll <span class="token function">C</span><span class="token punctuation">(</span>ll n<span class="token punctuation">,</span>ll m<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token punctuation">(</span>f<span class="token punctuation">[</span>n<span class="token punctuation">]</span><span class="token operator">*</span>inv<span class="token punctuation">[</span>f<span class="token punctuation">[</span>m<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">%</span>mod<span class="token operator">*</span>inv<span class="token punctuation">[</span>f<span class="token punctuation">[</span>n<span class="token operator">-</span>m<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token operator">%</span>mod<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> cin <span class="token operator">>></span> n<span class="token punctuation">;</span> f<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator"><=</span>maxn<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> f<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span>f<span class="token punctuation">[</span>i<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">*</span>i<span class="token punctuation">)</span><span class="token operator">%</span>mod<span class="token punctuation">;</span> inv<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">qPow</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span>mod<span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token operator">=</span>n<span class="token punctuation">;</span>i<span class="token operator">>=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">--</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> s<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span>s<span class="token punctuation">[</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator"><=</span>n<span class="token operator">?</span>s<span class="token punctuation">[</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">(</span>s<span class="token punctuation">[</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token operator"><=</span>n<span class="token operator">?</span>s<span class="token punctuation">[</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator"><=</span>n<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> dp<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token operator">=</span>n<span class="token punctuation">;</span>i<span class="token operator">>=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">--</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token keyword">if</span><span class="token punctuation">(</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token operator">+</span><span class="token number">1</span><span class="token operator"><=</span>n<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> dp<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token function">C</span><span class="token punctuation">(</span>s<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span>s<span class="token punctuation">[</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">*</span>dp<span class="token punctuation">[</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">%</span>mod<span class="token operator">*</span>dp<span class="token punctuation">[</span>i<span class="token operator">*</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token operator">%</span>mod<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> cout <span class="token operator"><<</span> dp<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator"><<</span> endl<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
学习的这位大佬的思路:
思路:假设d[i]是以完全二叉树i号位置为根结点的二叉子堆个数,则考虑我们现在需要把n个点放入这个完全二叉树里,显然根节点已经被确定,只能放最小的,然后假设左子树的节点个数为lsize,则我们需要从n-1个节点中选出lsize个节点放入左子树,选法一共组合数C(n-1,lsize)种,剩余的放在右子树中,所以d[i]=C(n-1,lsize)*d[i的左儿子]*d[i的右儿子];
注意:求组合数需要用快速幂,乘法逆元的知识。以i为根节点个数可以先用动态规划算出来,s[i]=s[i的左儿子]+s[i的右儿子];
求阶乘逆元O(nlongn),动态规划O(n);