@wsndy-xx
2018-05-20T07:50:12.000000Z
字数 1931
阅读 1096
题解
给定矩阵
定义矩阵
计算 的每个元素 %6 以后的和
考虑矩阵快速幂
令
那么矩阵 是 的
每次乘法的时间复杂度为
整个算法的时间复杂度为
显然无法接受
继续考虑优化算法
由于满足结合律
令
那么矩阵 是 的
写的有点啰嗦
#include <bits/stdc++.h>const int N = 1e3 + 10;const int K = 10, Mod = 6;#define LL long longLL A[N][K], B[K][N], E[K][K], G[N][K], Answer[N][N], n, k, Pow;struct Node {LL m[10][10];Node() {memset(m, 0, sizeof m);}void Clear() {for(int i = 1; i <= 7; i ++) m[i][i] = 1;}};Node Use;void Get_k_k() {for(int i = 1; i <= k; i ++)for(int j = 1; j <= k; j ++)for(int r = 1; r <= n; r ++)Use.m[i][j] += B[i][r] * A[r][j];}Node operator * (const Node &a, const Node &b) {Node ret;for(int i = 1; i <= k; i ++)for(int j = 1; j <= k; j ++)for(int r = 1; r <= k; r ++)ret.m[i][j] = (ret.m[i][j] + a.m[i][r] * b.m[r][j]) % Mod;return ret;}void Debug(Node a) {for(int i = 1; i <= k; i ++) {for(int j = 1; j <= k; j ++)std:: cout << a.m[i][j] << " ";std:: cout << "\n";}exit(0);}Node Ksm(Node a, int pow) {Node ret; ret.Clear();while(pow) {if(pow & 1) ret = ret * a;a = a * a;pow >>= 1;}return ret;}void Get_E(Node a) {for(int i = 1; i <= k; i ++)for(int j = 1; j <= k; j ++)E[i][j] = a.m[i][j];}void Work_nk() {for(int i = 1; i <= n; i ++)for(int j = 1; j <= k; j ++)for(int r = 1; r <= k; r ++)G[i][j] = (G[i][j] + A[i][r] * E[r][j] % Mod) % Mod;}void Work_kn() {for(int i = 1; i <= n; i ++)for(int j = 1; j <= n; j ++)for(int r = 1; r <= k; r ++)Answer[i][j] = (Answer[i][j] + G[i][r] * B[r][j] % Mod) % Mod;}int Get_Answer() {int ret(0);for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) ret += Answer[i][j];return ret;}int main() {while(1) {memset(E, 0, sizeof E);memset(G, 0, sizeof G);memset(Answer, 0, sizeof Answer);memset(Use.m, 0, sizeof Use.m);std:: cin >> n >> k;if(!n && !k) break;for(int i = 1; i <= n; i ++) for(int j = 1; j <= k; j ++) std:: cin >> A[i][j];for(int i = 1; i <= k; i ++) for(int j = 1; j <= n; j ++) std:: cin >> B[i][j];Get_k_k();Pow = n * n - 1;Node Ans = Ksm(Use, Pow);Get_E(Ans);Work_nk();Work_kn();std:: cout << Get_Answer() << "\n";}return 0;}