长寿花——组合数学和状态转移

长寿花

 

 

 

 

 

 

 

 

输入:

3 2 1000
3 1 2

输出: 

8

 

 

分析:

少一个mod调一天,啊啊啊,吐血的一天。先咕咕咕了,心累😭。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
#define debug printf("zjyvegetable\n")
#define int long long
#define R register
#define mod(x) ((x%p+p)%p)
inline int read(){
    int a=0,b=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')b=-1;c=getchar();}
    while(isdigit(c)){a=a*10+c-'0';c=getchar();}
    return a*b;
}
const int N=2e6+50,M=5e3+50;
int n,m,p,a[N],g[M][M],f[N],maxn,t[N],P[N],sum1,sum2;
signed main(){
    freopen("kalanchoe.in","r",stdin);
    freopen("kalanchoe.out","w",stdout);
    n=read();m=read();p=read();
    for(R int i=1;i<=n;i++){
        a[i]=read();
        maxn=max(maxn,a[i]);
    }
    g[0][0]=1;
    for(R int i=1;i<=maxn;i++){
        for(R int j=1;j<=((i<m)?i:m);j++){
            g[i][j]=mod(g[i-1][j-1]+mod(g[i-1][j]*(j-1)));
        }
    }
    t[0]=1;P[0]=1;
    for(R int i=1;i<=m;i++){
        t[i]=mod(t[i-1]*i);
        P[i]=mod(P[i-1]*(m-i+1));
    }
    sum2=1;f[0]=1;int rem;
    for(R int i=1;i<=n;i++){
        sum1=0;
        for(R int j=0;j<=a[i];j++){
            rem=f[j];
            f[j]=mod(mod(g[a[i]][j]*P[j])*sum2);
            if(j<=a[i-1])f[j]=mod(f[j]-mod(mod(rem*g[a[i]][j])*t[j]));
            sum1=mod(sum1+f[j]);
        }
        sum2=sum1;
    }
    printf("%lld\n",sum2);
    return 0;
}

 

posted @ 2020-08-02 20:24  zjy1412  阅读(147)  评论(0编辑  收藏  举报