zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    WiFi 和蓝牙一体的 ESP32 芯片及乐鑫官方的 Arduino 开发工具包
    给模块添加 USB 支持的 USB Host Shield Mini
    设备间数据通信 —— 串行外设接口(SPI)协议
    ESP32 开发板刷入 MicroPython
    芯片、模组、开发板以及业余爱好者如何选择
    快速了解线路板(PCB)基础知识
    终端发展过程及 tty、pty、pts 的区别
    时间类型和时间戳
    使用Qt实现一个必应壁纸客户端
    给网站添加Let's Encrypt的免费ssl证书
  • 原文地址:https://www.cnblogs.com/albert-biu/p/10294214.html
Copyright © 2011-2022 走看看