根據題目所給信息,要求所有
列一下,就是:
發現很像一顆二叉樹!就是一顆二叉樹。。
滿足根節點小於兩個兒子節點。
然後顯然有子結構,可以
對於一顆以
以
然而
預處理只用預處理到
當然也可以不用預處理逆元每次直接費馬小定理算,但是階乘是需要預處理的。
【代碼】
線性預處理逆元
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 1000001
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,mod;
int f[N],Fac[N],sz[N],Inv[N];
int Lucas(int x,int y)
{
if(x<y) return 0;
if(x<mod&&y<mod) return 1LL*Fac[x]*Inv[y]%mod*Inv[x-y]%mod;
return 1LL*Lucas(x/mod,y/mod)*Lucas(x%mod,y%mod)%mod;
}
int main()
{
n=read(),mod=read();Fac[0]=1;f[n+1]=1;Inv[1]=Inv[0]=1;int mx=min(n+1,mod);
for(int i=1;i<mx;i++) Fac[i]=1LL*Fac[i-1]*i%mod;
for(int i=2;i<mx;i++) Inv[i]=1LL*(mod-mod/i)*Inv[mod%i]%mod;
for(int i=1;i<mx;i++) Inv[i]=1LL*Inv[i]*Inv[i-1]%mod;
for(int i=n;i;i--)
{
static int l,r;l=i<<1,r=i<<1|1;
l=min(l,n+1),r=min(r,n+1);
sz[i]=sz[l]+sz[r]+1;
f[i]=1LL*f[l]*f[r]%mod*Lucas(sz[i]-1,sz[l])%mod;
}
printf("%d\n",f[1]);
return 0;
}
不預處理直接計算逆元
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 1000001
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,mod;
int f[N],Fac[N],sz[N];
int Qpow(int x,int y)
{
int rtn=1;
while(y){
if(y&1) rtn=1LL*x*rtn%mod;
x=1LL*x*x%mod;y>>=1;
}
return rtn;
}
int Lucas(int x,int y)
{
if(x<y) return 0;
if(x<mod&&y<mod) return 1LL*Fac[x]*Qpow(1LL*Fac[y]*Fac[x-y]%mod,mod-2)%mod;
return 1LL*Lucas(x/mod,y/mod)*Lucas(x%mod,y%mod)%mod;
}
int main()
{
n=read(),mod=read();Fac[0]=1;f[n+1]=1;
for(int i=1;i<N;i++) Fac[i]=1LL*Fac[i-1]*i%mod;
for(int i=n;i;i--)
{
static int l,r;l=i<<1,r=i<<1|1;
l=min(l,n+1),r=min(r,n+1);
sz[i]=sz[l]+sz[r]+1;
f[i]=1LL*f[l]*f[r]%mod*Lucas(sz[i]-1,sz[l])%mod;
}
printf("%d\n",f[1]);
return 0;
}