UVA11551 Experienced Endeavour —— 矩阵快速幂

题目链接:https://vjudge.net/problem/UVA-11551

题意:

给定一列数,每个数对应一个变换,变换为原先数列一些位置相加起来的和,问r次变换后的序列是多少

题解:

构造矩阵:要加的位置值为1,其余位置为0。然后用快速幂计算。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 //const int MOD = 1000000007;
17 const int MAXN = 1e6+100;
18 
19 const int MOD = 1000;
20 const int Size = 50;
21 struct MA
22 {
23     LL mat[Size][Size];
24     void init()
25     {
26         for(int i = 0; i<Size; i++)
27         for(int j = 0; j<Size; j++)
28             mat[i][j] = (i==j);
29     }
30 };
31 
32 MA mul(MA x, MA y)
33 {
34     MA ret;
35     memset(ret.mat, 0, sizeof(ret.mat));
36     for(int i = 0; i<Size; i++)
37     for(int j = 0; j<Size; j++)
38     for(int k = 0; k<Size; k++)
39         ret.mat[i][j] += (1LL*x.mat[i][k]*y.mat[k][j])%MOD, ret.mat[i][j] %= MOD;
40     return ret;
41 }
42 
43 MA qpow(MA x, LL y)
44 {
45     MA s;
46     s.init();
47     while(y)
48     {
49         if(y&1) s = mul(s, x);
50         x = mul(x, x);
51         y >>= 1;
52     }
53     return s;
54 }
55 
56 int main()
57 {
58     LL T, n, r, a[55];
59     scanf("%lld", &T);
60     while(T--)
61     {
62         scanf("%lld%lld", &n, &r);
63         for(int i = 0; i<n; i++)
64             scanf("%lld", &a[i]);
65 
66         MA s;
67         memset(s.mat, 0, sizeof(s.mat));
68         for(int i = 0; i<n; i++)
69         {
70             int m, x;
71             scanf("%d", &m);
72             while(m--)
73             {
74                 scanf("%d", &x);
75                 s.mat[i][x] = 1;
76             }
77         }
78 
79         s = qpow(s, r);
80         for(int i = 0; i<n; i++)
81         {
82             LL sum = 0;
83             for(int j = 0; j<n; j++)
84                 sum += s.mat[i][j]*a[j], sum %= MOD;
85             printf("%lld", sum);
86             if(i!=n-1) printf(" ");
87         }
88         printf("
");
89     }
90 }
View Code
原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8417676.html