此题题意很简单:就是求下面这个式子
x 取1-50 M,N取1-2×10^9
//首先可以看出这要用矩阵
但自己搞没搞出来,至于为什么,下文会提到,看了大牛报告,恍然大悟,自感弱菜。。。
//S(n) = sum(k^x * x^k)
//S(n+1) = S(n) + (n+1)^x * x^(n+1);
// = S(n) + x^(n+1) * ((x,0)*n^0 + (x,1)*n^1 + (x,2)*n^2,...二项展开)
//据此构造向量
//T(n) = (x^n*n^0,x^n*n^1,x^n*n^2,...x^n*n^x,S(n))
//T(n+1) =(x^(n+1)*(n+1)^0,x^(n+1)*(n+1)^1... x^(n+1)*n^(x+1),S(n+1));
//在这纸上乱搞一下可得出,(但我刚开始没想出(1+n)^x 可以用二项展开式来代替,所以。。)
//矩阵为
//x*(0,0) x*(1,0) x*(2,0) ... x*(x,0) x*(x,0)
//0 x*(1,1) x*(2,1) ... x*(x,1) x*(x,1)
//0 0 x*(2,2) ... x*(x,2) x*(x,2)
//.
//.
//.
//0 0 0 ... 0 1
贴代码:
#include <cstdio>
#include <cstring>
typedef __int64 ll;
const int size = 60;
ll M;
struct Matrix{
ll a[size][size];
int r,c; //行列
Matrix(){};
Matrix(int v)
{
for(int i = 0; i < size; i++)
for(int j = 0; j < size; j++)
if(i == j) a[i][j] = v;
else a[i][j] = 0;
}
void print()
{
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++)
printf("%lld ",a[i][j]);
printf("\n");
}
}
};
Matrix operator * (Matrix &ma,Matrix &mb)
{
Matrix mc(0);
for(int i = 0; i < ma.r; i++)
for(int j = 0; j < mb.c; j++)
for(int k = 0; k < ma.c; k++)
mc.a[i][j] = (mc.a[i][j] + ma.a[i][k] * mb.a[k][j]) % M;
mc.r = ma.r;
mc.c = mb.c;
return mc;
}
Matrix operator ^ (Matrix &a,int b)
{
Matrix ans(1);
ans.c = a.c;
ans.r = a.r;
while(b){
if(b & 1) ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
ll cb[size][size];
void init_cb(void)
{
for(int i = 0; i < size; i++){
cb[0][i] = 0;
cb[i][0] = 1;
}
for(int i = 1; i < size; i++)
for(int j = 1; j < size; j++)
cb[i][j] = cb[i-1][j] + cb[i-1][j-1];
}
void build_matrix(Matrix &A,Matrix &T,int x)
{
A.r = x + 2;
A.c = x + 2;
for(int i = 0; i < A.r; i++)
for(int j = i; j < A.c-1; j++){
A.a[i][j] = x * cb[j][i] % M;
}
for(int i = 0; i < A.r; i++)
A.a[i][A.c-1] = A.a[i][A.c-2];
A.a[A.r-1][A.c-1] = 1;
///
T.r = 1;T.c = x+2;
for(int i = 0; i < T.c; i++)
T.a[0][i] = x;
}
int main()
{
ll N,x;
while(1){
scanf("%I64d%I64d%I64d",&N,&x,&M);
if(N < 0) break;
init_cb();
Matrix A,T;
build_matrix(A,T,x);
// A.print(); T.print();
A = A ^ (N-1);
T = T * A;
// T.print();
printf("%I64d\n",T.a[0][T.c-1]);
}
return 0;
}
这题还得到一个小经验,用long long会tle,用__int64就A了,不知道为什么。。。,以后能用__int64就用__int64啊。。