Operands ~ Matrix Fast Power Solution

Link: https://www.nowcoder.com/acm/contest/109/C
Source: Niuke.com

Topic description

Given an array a of length n, define an operation as:
1. Calculate an array s of length n such that s i = (a[1] + a[2] + ... + a[i]) mod 1,000,000,007 ;
2. Execute a = s;
now ask what a looks like after k operations.

Enter description:

The first line contains two integers n, k(1 <= n <= 2000, 0 <= k <= 1,000,000,000); 
the second line contains n integers representing an array of a (0 <= a
i
<= 1,000,000,000)。

Output description:

A line of n integers represents the answer.
Example 1

enter

3 1
1 2 3

output

1 3 6
Example 2

enter

5 0
3 14 15 92 6

output

3 14 15 92 6 


This problem is very easy to find matrix A,
1 1 1 1 1
0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
0 0 0 0 1
is such a matrix,
but note that n has 2000 ;
So it's not enough to write this matrix directly, it's OK to compress it

   mat operator * (mat & a) {
        mat ans;
        for (int i = 0 ; i < maxn ; i++) {
                for (int j = 0 ; j <= i ; j++ ) {
                         ans.m[i] = (ans.m[i] + m[j] * a.m[i - j]) % mod;
               }
        }
        return ans;
   }

  Since the regularity is very obvious, it can be stored in a one-dimensional array

  

Then there's the regular fast exponentiation of matrices. 
But for this question, they said that there are other solutions
to find rules that seem to be able to do it, but I won't.
I can only think of the method of
matrix fast exponentiation. The matrix fast exponentiation is a bit slow, but it is OK to AC.


 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <vector>
 4 #include <queue>
 5 #include <cstring>
 6 #include <string>
 7 #include <map>
 8 using namespace std;
 9 const int maxn = 2000;
10 const long  long  mod = 1e9 + 7;
11 typedef long long LL;
12 struct mat {
13     LL m[maxn];
14     mat() {
15         memset(m, 0, sizeof(m));
16     }
17     mat operator * (mat & a) {
18         mat ans;
19         for (int i = 0 ; i < maxn ; i++) {
20             for (int j = 0 ; j <= i ; j++ ) {
21                 ans.m[i] = (ans.m[i] + m[j] * a.m[i - j]) % mod;
22             }
23         }
24         return ans;
25     }
26 };
27 mat modexp(mat a, LL b) {
28     mat ans;
29     for (int i = 0 ; i < maxn ; i++) ans.m[i] = 1;
30     while(b) {
31         if (b & 1 ) ans = ans * a;
32         b = b >> 1;
33         a = a * a;
34     }
35     return ans;
36 }
37 int main() {
38     LL n, k;
39     mat a, b;
40     scanf("%lld%lld", &n, &k );
41     for (int i = 0 ; i < n ; i++) {
42         scanf("%lld", &b.m[i]);
43         a.m[i] = 1;
44     }
45     if (k == 0) {
46         for (int i = 0 ; i < n ; i++) {
47             printf("%lld", b.m[i]);
48             if (i != n - 1) printf(" ");
49             else printf("\n");
50         }
51         printf("\n");
52     } else {
53         a = modexp(a, k - 1);
54         b = b * a;
55         for (int i = 0 ; i < n ; i++) {
56             printf("%lld", b.m[i]);
57             if (i != n - 1) printf(" ");
58             else printf("\n");
59         }
60     }
61     return 0;
62 }

 



Guess you like

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