Total Submission(s): 3036 Accepted Submission(s): 1834
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .
Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
In each case, there will be two lines.
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9.
利用矩阵快速可以快速取模,求取递推式
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#define MAX 15
using namespace std;
int n,m,size = 10;
struct mat
{
int a[MAX][MAX];
mat ( )
{
memset ( a , 0 , sizeof ( a ));
}
};
mat multi ( mat m1 , mat m2 )
{
mat ans = mat ();
for ( int i = 1 ; i <= size ; i++ )
for ( int j = 1 ; j <= size ; j++ )
if ( m1.a[i][j] )
for ( int k =1 ; k <= size ; k++ )
ans.a[i][k] = ( (long long )(ans.a[i][k]) + (long long)(m1.a[i][j]) *(long long)(m2.a[j][k] ))%m;
return ans;
}
mat quickmulti ( mat m , int n )
{
mat ans = mat ();
for ( int i = 1; i <= size ; i++ ) ans.a[i][i] = 1;
while ( n )
{
if ( n&1 ) ans = multi ( m , ans );
m = multi ( m ,m );
n >>= 1;
}
return ans;
}
void debug ( mat A )
{
cout << "##################" << endl;
for ( int i = 1 ; i <= size ; i++ )
{
for ( int j = 1 ; j <= size ; j++ )
printf ( "%d " , A.a[i][j] );
puts ("");
}
cout << "#####################"<< endl;
}
int main ( )
{
while ( ~scanf ( "%d%d" , &n , &m ))
{
mat A;
mat res;
for ( int i = 1 ; i <= 10 ; i++ )
scanf ( "%d" , &A.a[i][1] );
for ( int i = 1 ; i <= 9 ; i++ )
A.a[i][i+1] = 1;
for ( int i = 1 ; i <= size ; i++ )
res.a[1][i] = 10-i;
if ( n < 10 )
{
printf ( "%d\n" , n %m );
continue;
}
//debug ( A );
A = quickmulti ( A , n- 9 );
//cout << "A : "<< endl;
// debug ( A );
//cout << "res : " << endl;
// debug ( res );
res = multi ( res , A );
//debug ( res );
printf ( "%d\n" , res.a[1][1] );
}
}