[National Team] calc

topic

Obviously there is a violent \ (dp \)

\ (dp_ {i, j} \) representing the forward \ (I \) the number of the selected \ (J \) th answers

Obviously transfer

\[dp_{i,j}=dp_{i-1,j}+dp_{i-1,j-1}\times i\]

Since the element is in order, the answer is \ (dp_ {A, n} \ times n! \)

Complexity is \ (O (nA) \) apparently could not pass

We look at the transfer, a simple transposition

\[dp_{i,j}-dp_{i-1,j}=dp_{i-1,j-1}\times i\]

If we put \ (dp_ {i, j} \) as a and \ (i \) related to the polynomial, then \ (dp_ {i, j} -dp_ {i-1, j} \) is to do a difference, or a polynomial obtained was found, but a ratio of the number \ (dp_ {j-1} \) high a polynomial

Obviously \ (dp_ {j} \) than the \ (dp_ {j-1} \) high twice, \ (dp_ {0} \) a \ (0 \) order polynomial, thereby \ ( dp_ {j} \) a \ (2J \) polynomial

Thus for \ (dp_ {A, n} \) is a \ (2N \) degree polynomial, we force the dp \ (2N \) after the value of a Lagrange interpolation strong enough

Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
const int maxn=1005;
int dp[maxn][505],n,m,mod;
inline int ksm(int a,int b) {
    int S=1;
    for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) S=1ll*S*a%mod;
    return S;
}
int main() {
    scanf("%d%d%d",&m,&n,&mod);dp[0][0]=1;
    for(re int i=1;i<=2*n+1;i++) {
        dp[i][0]=dp[i-1][0];
        for(re int j=1;j<=i;j++) 
            dp[i][j]=(dp[i-1][j]+1ll*dp[i-1][j-1]*i%mod)%mod;
    }
    int ans=0;
    for(re int i=1;i<=2*n+1;i++) {
        int q=1,p=1;
        for(re int j=1;j<=2*n+1;j++)
        if(i!=j) p=1ll*(m-j)*p%mod,q=1ll*(i-j)*q%mod;
        q=(q+mod)%mod,p=(p+mod)%mod;
        ans=(ans+1ll*dp[i][n]*p%mod*ksm(q,mod-2)%mod)%mod;
    }
    for(re int i=1;i<=n;i++) ans=1ll*ans*i%mod;
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/asuldb/p/10927134.html