# 堆的计数

**题目描述**

我们知道包含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

下面的代码实现了这一功能，请你补全空白处缺失的代码：

```cpp
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 100000;
ll s[maxn + 10], dp[maxn + 10], inv[maxn + 10], f[maxn + 10];
ll n;
ll mod = 1000000009;
ll qPow(ll a, ll b)
{
    ll ans = 1;
    while (b != 0)
    {
        if (b & 1)
        {
            ans = ans * a % mod;
        }
        a = a * a % mod;
        b >>= 1;
    }
    return ans % mod;
}
ll C(ll n, ll m)
{
    return (f[n] * inv[f[m]]) % mod * inv[f[n - m]] % mod;
}

int main()
{
    cin >> n;
    f[0] = 1;
    for (int i = 1; i <= maxn; i++)
    {
        f[i] = (f[i - 1] * i) % mod;
        inv[i] = qPow(i, mod - 2);
    }
    for (int i = n; i >= 1; i--)
    {
        s[i] = (s[i * 2 + 1] <= n ? s[i * 2 + 1] : 0) + (s[i * 2] <= n ? s[i * 2] : 0) + 1;
    }
    for (int i = 1; i <= n; i++)
    {
        dp[i] = 1;
    }
    for (int i = n; i >= 1; i--)
    {
        if (i * 2 + 1 <= n)
        {
            __________________
        }
    }
    cout << dp[1] << endl;
    return 0;
}
```

## aop

### before

```cpp

```
### after

```cpp

```

## 答案

```cpp
dp[i] = (C(s[i] - 1, s[i * 2 + 1]) * dp[i * 2 + 1]) % mod * dp[i * 2] % mod;
```
## 选项


### A

```cpp
dp[i] = (C(s[i], s[i * 2 + 1]) * dp[i * 2 + 1]) % mod * dp[i * 2 + 1] % mod;
```

### B

```cpp
dp[i] = (C(s[i] - 1, s[i * 2]) * dp[i * 2]) % mod * dp[i * 2] % mod;
```

### C

```cpp
dp[i] = (C(s[i] + 1, s[i * 2 + 1]) * dp[i * 2 + 1]) % mod * dp[i * 2] % mod;
```
