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= 

 

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;
}

 

posted @ 2019-01-20 11:01  Albert_liu  阅读(197)  评论(0编辑  收藏  举报