0
点赞
收藏
分享

微信扫一扫

HDU 3483 A Very Simple Problem 矩阵构造


A Very Simple Problem

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 739    Accepted Submission(s): 378


Problem Description


This is a very simple problem. Given three integers N, x, and M, your task is to calculate out the following value:



HDU 3483 A Very Simple Problem 矩阵构造_HDU



Input


There are several test cases. For each case, there is a line with three integers N, x, and M, where 1 ≤ N, M ≤ 2*10 9, and 1 ≤ x ≤ 50.
The input ends up with three negative numbers, which should not be processed as a case.


 


Output


For each test case, print a line with an integer indicating the result.



Sample Input


100 1 10000
3 4 1000
-1 -1 -1


 


Sample Output


5050 444


/*
HDU 3483 矩阵构造

不会 转载别人的 以后再看把
作为乘数项的矩阵不得与N有关,只能与x有关
F(n+1) = F(n) + x^(n+1) * (n+1)^x 把(n+1)^x拆分
=F(n) + ( C(x,0)* n^x + C(x,1)* n^(x-1) + ... + C(x,x-1)*n +1)* x^(n+1)
把x^(n+1)分成x^n*x放入进去:
=F(n) + (C(x,0)* n^x* (x^n) + C(x,1)*n^(x-1)*(x^n)+ ... +C(x,x-1)*n*(x^n)+1*(x^n))*x
=F(n) + (x*C(x,0)* n^x *(x^n) + x*C(x,1)* n^(x-1)*x^n+...)

x^(n+1)*(n+1)^x 写成了sum{g(i,n)*const(i)},const(i)与n无关,
可以乘数项矩阵的一部分),而g(i,n)可以作为最终矩阵的一部分
更重要的是,g(i,n)要和f(n)放在一起构成最终矩阵,也就是g(i,n)如何表达?

g(i+1,n) =(i+1)^x*(x^n) = (C(i,0)*i^x + C(i,1)*i^(x-1) + ..+C(i,i)*i^0) *(x^(n+1))
= (C(i,0)*x*t0 + C(i,1)*x*t1 + ...+C(i,i)*x*ti)
tj = i^j*(x^n) = g(j,n-1) 0<=j<=i
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>

#define N 60
#define cl(a) memset(a,0,sizeof(a))
#define ss(a) scanf("%d",&a)
#define ll __int64
#define pb push_back

using namespace std;

ll a[N][N][N],c[N][N],r[N];
vector<ll>gener;
int mod,k;

void generate_cmb()
{
int i,j;
cl(c);
for (i=0;i<=k;i++)
for (j=0;j<=i;j++)
{
if (j==0) c[i][j]=1;
else if (j>i-j) c[i][j]=c[i][i-j];
else c[i][j]=c[i-1][j]+c[i-1][j-1];
}
}

void init()
{
int i,j;
generate_cmb();
cl(a);cl(r);
for (i=0;i<=k;i++)
for (j=0;j<=k;j++)
a[0][i][j]=(k*c[i][j])%mod;
for (j=0;j<=k;j++) a[0][k+1][j]=(k*c[k][j])%mod;
a[0][k+1][k+1]=1;
for (i=0;i<=k+1;i++) r[i]=k;
}

void rmul(int x)
{
int u,v,w;
for (u=0;u<=k+1;u++)
for (v=0;v<=k+1;v++)
{
for (w=0;w<=k+1;w++)
a[x+1][u][v]=(a[x+1][u][v]+(a[x][u][w]*a[x][w][v])%mod)%mod;
}
}

void mul(int x)
{
int u,v;
ll t;
gener.clear();
for (u=0;u<=k+1;u++)
{
t=0;
for (v=0;v<=k+1;v++) t=(t+(a[x][u][v]*r[v])%mod)%mod;
gener.pb(t);
}
for (int i=0;i<=k+1;i++) r[i]=gener[i];
}

void quick(int n)
{
int i=0;
while (n>0)
{
if (n&1) mul(i);
rmul(i);
n>>=1;
i++;
}
}

int main()
{
int n;
while (ss(n)!=EOF)
{
ss(k);ss(mod);
if (n<0&&k<0&&mod<0) break;
if (n==1)
{
cout<<k%mod<<endl;
continue;
}
init();
quick(n-1);
cout<<r[k+1]<<endl;
}
return 0;
}






举报

相关推荐

0 条评论