https://blog.csdn.net/ez_yww/article/details/77221338
讲的很好不做解释,具体看代码
// luogu-judger-enable-o2 //dp[i][j]在前i个数选j个数的价值和 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define ll long long #define dul(p) (((p)%MOD+MOD)%MOD) using namespace std; const int maxn=1000000+10101; inline int read(){ int x=0,f=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0'; return x*f; } ll MOD,A,n,dp[1001][1001],x[maxn],y[maxn]; ll power(ll x,ll y){ ll ans=1; while(y){ if(y&1)ans=(ans*x)%MOD; x=(x*x)%MOD; y>>=1; } return (ans%MOD+MOD)%MOD; } void lar(ll limit){ ll ans=0; for(int i=0;i<=limit;i++){ ll a1=1,b1=1; for(int j=0;j<=limit;j++){ if(i==j)continue; a1=a1*(A-x[j])%MOD; b1=b1*(x[i]-x[j])%MOD; } ans=dul(ans+dul(y[i]*a1%MOD*power(b1,MOD-2))); } printf("%lld",(ans%MOD+MOD)%MOD); return ; } int main(){ A=read();n=read();MOD=read(); dp[0][0]=1; for(int i=1;i<=(n<<1);i++){ dp[i][0]=1; for(int j=1;j<=i;j++)dp[i][j]=(dp[i-1][j-1]*i%MOD*j%MOD+dp[i-1][j])%MOD; } if((n<<1)>=A){printf("%lld",(dp[A][n]%MOD+MOD)%MOD);return 0;} for(int i=0;i<=(n<<1);i++)x[i]=i,y[i]=dp[i][n]; lar(n<<1); return 0; }