根据Pi>Pi/2可以看出来这是一个二叉树
所以我们可以用树形DP的思想
f[i]=f[i<<1]*f[i<<1|1]*C(s[i]-1,s[i<<1]),s是子树大小
然后求组合数可以用卢卡斯定理
BZ上加强数据后我那个线性求n!逆元就挂掉了,于是就直接算了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+5;
ll f[N<<1],fac[N],inv[N],s[N<<1];
ll n,mod;
ll qmod(ll a,ll b)
{
ll ans=1;
while(b)
{
if(b&1)ans=ans*a%mod;
a=a*a%mod;b>>=1;
}
return ans;
}
ll C(ll a,ll b)
{
if(a<b)return 0;
if(a<mod&&b<mod)return fac[a]*qmod(fac[b]*fac[a-b]%mod,mod-2)%mod;
return C(a/mod,b/mod)*C(a%mod,b%mod)%mod;
}
int main()
{
scanf("%lld%lld",&n,&mod);
fac[0]=1;
for(int i=1;i<=n;++i)fac[i]=i*fac[i-1]%mod;
for(int i=n;i;--i)
{
s[i]=s[i<<1]+s[(i<<1)|1]+1;f[i]=1;
if((i<<1)<=n)f[i]=f[i]*f[i<<1]%mod;
if((i<<1|1)<=n)f[i]=f[i]*f[i<<1|1]%mod;
f[i]=f[i]*C(s[i]-1,s[i<<1])%mod;
}
printf("%lld",f[1]);
return 0;
}
转载于:https://www.cnblogs.com/nbwzyzngyl/p/8416411.html