A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3036    Accepted Submission(s): 1834


Problem Description
Lele now is thinking about a simple function f(x).

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.
 

Input
The problem contains mutiple test cases.Please process to the end of file.
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.
 

Output
For each case, output f(k) % m in one line.
 

Sample Input
10 9999 1 1 1 1 1 1 1 1 1 1 20 500 1 0 1 0 1 0 1 0 1 0
 

Sample Output
45 104
 

Author
linle
 

Source
题目分析:
利用矩阵快速可以快速取模,求取递推式
#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] );
    }
}