长寿花——组合数学和状态转移
长寿花
输入:
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; }