是我想复杂了
首先发现大于关系构成了一棵二叉树的结构,于是树形dp 设f[i]为i点的方案数,si[i]为i点的子树大小,递推式是\( f[i]=f[i*2]*f[i*2+1]*C_{si[i]-1}^{si[i*2]} \) 组合数用Lucas求#include#include using namespace std;long long n,p,f[5000005],jc[5000005],s[5000005];long long ksm(long long a,long long b){ long long r=1; while(b) { if(b&1) r=r*a%p; a=a*a%p; b>>=1; } return r;}long long C(long long x,long long y){ if(y>x) return 0; return jc[x]*ksm(jc[y]*jc[x-y]%p,p-2)%p;}long long luc(long long x,long long y){ if(!y) return 1; return C(x%p,y%p)*luc(x/p,y/p)%p;}void dfs(long long u){ s[u]=1;f[u]=1;f[u<<1]=1;f[u<<1|1]=1; if((u<<1)<=n) dfs(u<<1),s[u]+=s[u<<1]; if((u<<1|1)<=n) dfs(u<<1|1),s[u]+=s[u<<1|1]; f[u]=f[u<<1]*f[u<<1|1]%p*luc(s[u]-1,s[u<<1])%p;}int main(){ scanf("%lld%lld",&n,&p); jc[0]=jc[1]=1; for(long long i=2;i<=n;i++) jc[i]=jc[i-1]*i%p; dfs(1); printf("%lld",f[1]); return 0;}