[Matrix fast power template] [Hangdian OJ1757]

http://acm.hdu.edu.cn/showproblem.php?pid=1757

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

 Topic analysis: see 1) f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + ... + a9 * f(x-10) ;[a recursion]

        2) k<2*10^9 , m < 10^5 [large data]

      I know it's a fast power of the matrix [Okay.. I didn't know it before.. qaq..]

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 long long n,k;
 7 void mul(long long wqw[10],long long tat[10][10])
 8 {
 9     long long or2[10];
10 //    cout << 
11     memset(or2,0,sizeof(or2));
12     for(int i = 0 ; i < 10  ; i++)
13     {
14         for(int j = 0 ; j < 10 ; j++)
15         {
16             or2[i]+=(wqw[j]*(tat[j][i]))%k;
17             or2[i]%=k;
18         }
19     }
20     memcpy(wqw,or2,sizeof(or2));
21 }
22 void mulself(long long awa[10][10])
23 {
24     long long or3[10][10];
25     memset(or3,0,sizeof(or3));
26     for(int i = 0; i < 10 ; i++)
27     {
28         for(int j = 0 ; j< 10 ; j++)
29         {
30             for(int kk = 0 ; kk < 10 ; kk++)
31             {
32                 or3[i][j]+=((awa[i][kk])%k)*((awa[kk][j])%k)%k;
33                 or3[i][j]%=k;
34             }
35         }
36     }
37     memcpy(awa,or3,sizeof(or3));
38 }
39 int main()
40 {
41     while(scanf("%lld%lld",&n,&k)==2)
42     {
43     
44     long long qaq[10][10];
45     long long qwq[10];
46     long long orz[10]={9,8,7,6,5,4,3,2,1,0};
47     memset(qaq,0,sizeof(qaq));
48     for(int i = 0 ; i < 10 ; i++)
49     {
50         scanf("%lld",&qaq[i][0]);
51     }
52     for(int i = 1 ; i < 10; i++)
53     {
54         qaq[i-1][i]=1;
55     }
56     if(n<10)
57     {
58         printf("%lld\n",n%k);
59     }
60     else
61     {
62         n=n-9;
63         while(n)
64         {
65             if(n&1)mul(orz,qaq);
66             mulself(qaq);
67             n/=2;
68         }
69         cout  <<orz[0]%k<<endl;
70     }
71 }
72     return 0;
73 }

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325892022&siteId=291194637