题意:给你n个不同的数问你能构成多少个不同的二叉堆
显然不能枚举,我们考虑用递推
我们令f[i]表示以i为根的二叉堆有多少种
令l,r为i的左右儿子,令size[i]为以i为根的堆的大小
那么显然,f[i]=f[l]*f[r]*C(size[i]-1,size[l]),因为n个数互不相同,所以没有重复
相当于是1~size[i]这几个数填进这个堆中,那么显然根只能填最大那个,让后在剩下的数选择size[l]个即可
因为堆有两种,大根堆和小根堆,所以答案要乘2
#include<stdio.h>
#define M 1000000007
#define L long long
#define N 5000010
L inv[N],js[N],f[N];
int n,sz[N];
inline L C(int n,int m){
return js[n]*inv[n-m]%M*inv[m]%M;
}
inline L pow(L x,int k){
L S=1;
for(;k;x=x*x%M,k>>=1)
if(k&1) S=S*x%M;
return S;
}
int main(){
scanf("%d",&n);
*js=*i