/**//* 题意:给出N,x,M 要计算 N ∑(k^x)*(x^k) MOD M k=1 x 用到二项式定理,(n+1)^x = ∑C(x,k)n^k k=0 然后构造矩阵,求和 S(n)表示前n项和 */ #include<cstdio> #include<cstring>
long long C[55][55],A[55][55],start[55]; int M,N,x;
void init() { for(int i=0;i<=x;i++)C[i][0]=C[i][i]=1; for(int i=2;i<=x;i++) for(int j=1;j<i;j++) { C[i][j]=C[i-1][j]+C[i-1][j-1]; if(C[i][j]>=M)C[i][j]%=M; } //init A [0x+1][0x+1] memset(A,0,sizeof(A)); for(int j=0;j<=x;j++) for(int i=0;i<=j;i++) { A[i][j]=x*C[j][i]; if(A[i][j]>=M)A[i][j]%=M; } for(int i=0;i<=x;i++) { A[i][x+1]=x*C[x][i]%M; if(A[i][x+1]>=M)A[i][x+1]%=M; } A[x+1][x+1]=1; for(int j=0;j<=x+1;j++)start[j]=x;//N=1时 } void mul(long long A[][55],long long B[][55])//A=A*B { long long R[55][55]={0}; for(int k=0;k<=x+1;k++) for(int i=0;i<=x+1;i++) if(A[i][k]) for(int j=0;j<=x+1;j++) { R[i][j]+=A[i][k]*B[k][j]; if(R[i][j]>=M)R[i][j]%=M; } for(int i=0;i<=x+1;i++) for(int j=0;j<=x+1;j++) A[i][j]=R[i][j]; } void pow(long long m[][55],int n)//m=A^n { if(n==1) { for(int i=0;i<=x+1;i++) for(int j=0;j<=x+1;j++) m[i][j]=A[i][j]; return ; } pow(m,n/2); mul(m,m); if(n&1)mul(m,A); } int main() { //freopen("in","r",stdin); while(scanf("%d%d%d",&N,&x,&M),N>0) { if(N==1){printf("%d\n",x%M);continue;} init(); long long ans[55][55]; pow(ans,N-1); long long res=0; for(int i=0;i<=x+1;i++) res+=start[i]*ans[i][x+1]; printf("%I64d\n",res%M); } return 0; }
|
|
常用链接
随笔分类
Links
搜索
最新评论
|
|