UPC10806 矩阵快速幂
题目描述
给定一个n*n的矩阵A以及一个正整数k,计算S=A1+A2+A3+⋯+Ak
输入
输入只有一组测试数据。输入的第一行包括三个正整数 n,k,m。接下来的 n 行每行包括 n 个非负整数(在[0,32768)之间),按照行优先的顺序输入矩阵 A 的元素。
输出
输出 S 中每一个元素 mod(%)m 以后的值
样例输入
1 998 1007
11
样例输出
360
提示
第一次写矩阵递推,算是入门题吧。
输入矩阵A,单位矩阵one,零矩阵zero。
F(n) = [An+1,Sn]
F(0) = [A,zero]
h=
h=
F(1) = [A,zero]*h;
F(k) = [A,zero]*hk;
#include "bits/stdc++.h" using namespace std; typedef long long ll; int n, mod, k; struct matrix { ll a[35][35]; }; struct mm { matrix a[5][5]; }; matrix zero, one, A; matrix add(matrix a, matrix b) { matrix c; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { c.a[i][j] = (a.a[i][j] + b.a[i][j]) % mod; } } return c; } matrix mul(matrix a, matrix b) { matrix c; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { c.a[i][j] = 0; for (int k = 0; k < n; k++) { c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j]) % mod; } } } return c; } mm smul(mm a, mm b) { mm c; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { c.a[i][j] = zero; for (int k = 0; k < 2; k++) { c.a[i][j] = add(c.a[i][j], mul(a.a[i][k], b.a[k][j])); } } } return c; } void init() { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { zero.a[i][j] = 0; one.a[i][j] = 0; } } //one.a[0][0] = 1; //one.a[1][1] = 1; for(int i=0;i<n;i++){ //cout<<i<<endl; one.a[i][i] = 1; } } mm powmod(mm a, int b) { mm ret; ret.a[0][0] = one; ret.a[1][1] = one; ret.a[0][1] = zero; ret.a[1][0] = zero; while (b) { if (b & 1) ret = smul(ret, a); a = smul(a, a); b >>= 1; } return ret; } int main() { //freopen("input.txt", "r", stdin); cin >> n >> k >> mod; init(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> A.a[i][j]; } } mm f, h; f.a[0][0] = A; f.a[1][0] = zero; f.a[0][1] = one; f.a[1][1] = one; f = powmod(f, k); h.a[0][0] = A; h.a[0][1] = zero; h = smul(h, f); matrix ans = h.a[0][1]; int flag = 0; if (k != 0) { for (int i = 0; i < n; i++) { flag = 0; for (int j = 0; j < n; j++) { if (flag) cout << " "; cout << (ans.a[i][j] + mod) % mod; flag = 1; } cout << endl; } } else { for (int i = 0; i < n; i++) { flag = 0; for (int j = 0; j < n; j++) { if (flag) cout << " "; cout << (one.a[i][j] + mod) % mod; flag = 1; } cout << endl; } } return 0; }