作为一个因为极度畏惧数学

而选择成为一名OIer的蒟蒻

终于还是迎来了要面对的这一天


一般题目中矩阵运算好像只用到矩阵乘法

(或许只是蒟蒻我做的题太少)

而且矩阵的乘法也是较难理解的一部分

所以就简单讲讲矩阵乘法

如图

矩阵A*B就是用A的每一行依次乘B的每一列

具体就是A的第i行中每一个数对应相乘B的第j列每个数

每个相乘所得结果相加

最后放置于C矩阵的第i行第j号位

所以矩阵乘法中A的列数必须等于B的行数

(虽然第一次看确实有些绕,但它用起来真的妙啊~妙啊~)

上一个矩阵A*B的代码

(这里以正方形矩阵为例)

for(ll i=1;i<=n;i++)//枚举A的每一行
for(ll j=1;j<=n;j++)//枚举B的每一列
for(ll k=1;k<=n;k++)//k既是A的列数,也是B的行数
C.a[i][j]+=A.a[i][k]*B.a[k][j];

这里运算的复杂度为O(n^3)

一般题目已经够用

有O(n^2.7)的算法太 太 太复杂

所以其实可以不用在意的啦

神奇的一点

矩阵乘法也是支持结合律的!!!

但是它不支持分配律

这是很重要的一点

因为这决定了他也同样可以快速幂

(你别告诉我不知道快速幂是什么 = = )

所以就先上一道最最基础的矩阵运算入门操作

题目传送门 啦~啦~啦~


题目描述

给定n*n的矩阵A,求A^k

输入输出格式

输入格式:

第一行,n,k

第2至n+1行,每行n个数,第i+1行第j个数表示矩阵第i行第j列的元素

输出格式:

输出A^k

共n行,每行n个数,第i行第j个数表示矩阵第i行第j列的元素,每个元素模10^9+7

输入样例

2 1

1 1

1 1

输出样例

1 1

1 1

说明

n<=100, k<=10^12, |矩阵元素|<=1000


这次具体解释看代码注释啦~啦~啦~

(不要吐槽我的蜜汁缩进)

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;

ll read()
{
    ll f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return x*f;
}

void print(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

ll n,m;
ll ans;
const ll mod=1000000000+7;
struct node{ll a[110][110];}d;
//用结构体储存矩阵,以便调用快速幂后返回整个矩阵

node quick_pow(node f,ll k)
{
    if(k==1) return f;
    //若指数为1,则直接返回矩阵

    else if(k%2==1)
    {
        //指数为奇数,返回k-1次方乘一次方
        node temp=quick_pow(f,k-1);
        node ans;
        for(ll i=1;i<=n;i++)
        for(ll j=1;j<=n;j++)
        for(ll k=1;k<=n;k++)
        ans.a[i][j]+=(f.a[i][k]*temp.a[k][j])%mod,ans.a[i][j]%=mod;
        return ans;
    }

    else if(k%2==0)
    {
        //指数为偶数,计算矩阵的k/2次方,在返回平方
        node temp=quick_pow(f,k/2);
        node ans;
        for(ll i=1;i<=n;i++)
        for(ll j=1;j<=n;j++)
        for(ll k=1;k<=n;k++)
        ans.a[i][j]+=(temp.a[i][k]*temp.a[k][j])%mod,ans.a[i][j]%=mod;
        return ans;
    }
}

int main()
{
    n=read();m=read();
    for(ll i=1;i<=n;i++)
    for(ll j=1;j<=n;j++)
    d.a[i][j]=read();//读入初始矩阵

    node ans=quick_pow(d,m);//快速幂

    for(ll i=1;i<=n;i++)
    {
        for(ll j=1;j<=n;j++)
        print(ans.a[i][j]),printf(" ");
        printf("\n");
    }
    return 0;
}

洛谷P3390【模板】矩阵快速幂——矩阵运算入门笔记的更多相关文章

  1. 【洛谷P3390】矩阵快速幂

    矩阵快速幂 题目描述 矩阵乘法: A[n*m]*B[m*k]=C[n*k]; C[i][j]=sum(A[i][1~n]+B[1~n][j]) 为了便于赋值和定义,我们定义一个结构体储存矩阵: str ...

  2. 3990 [模板]矩阵快速幂 洛谷luogu

    题目背景 矩阵快速幂 题目描述 给定n*n的矩阵A,求A^k 输入输出格式 输入格式: 第一行,n,k 第2至n+1行,每行n个数,第i+1行第j个数表示矩阵第i行第j列的元素 输出格式: 输出A^k ...

  3. ACM-ICPC 2018 焦作赛区网络预赛- L:Poor God Water(BM模板/矩阵快速幂)

    God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him t ...

  4. 【洛谷 p3390】模板-矩阵快速幂(数论)

    题目:给定n*n的矩阵A,求A^k. 解法:利用矩阵乘法的定义和快速幂解答.注意用负数,但是数据太弱没有卡到我......(P.S.不要在 typedef long long  LL; 前使用 LL. ...

  5. 洛谷 P1965 转圈游戏 —— 快速幂

    题目:https://www.luogu.org/problemnew/show/P1965 居然真的就只是 ( x + m * 10k % n ) % n 代码如下: #include<ios ...

  6. POJ 3070 Fibonacci 矩阵快速幂模板

    Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18607   Accepted: 12920 Descr ...

  7. 模板【洛谷P3390】 【模板】矩阵快速幂

    P3390 [模板]矩阵快速幂 题目描述 给定n*n的矩阵A,求A^k 矩阵A的大小为n×m,B的大小为n×k,设C=A×B 则\(C_{i,j}=\sum\limits_{k=1}^{n}A_{i, ...

  8. 【模板】矩阵快速幂 洛谷P2233 [HNOI2002]公交车路线

    P2233 [HNOI2002]公交车路线 题目背景 在长沙城新建的环城公路上一共有8个公交站,分别为A.B.C.D.E.F.G.H.公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另 ...

  9. 洛谷P1939【模板】矩阵加速(数列)+矩阵快速幂

    思路: 这个 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 可以想成: [a(n) ] [1 0 1] [a(n-1)   ] [a(n-1) ] =    ...

随机推荐

  1. dede后台出现   保存目录数据时失败,请检查你的输入资料是否存在问题

    dede 5.7无法增加顶级/二级栏目,保存目录数据时失败,请检查你的输入资料是否存在问题!执行了SQL还是不行 解决档案:用正常可以添加栏目的,将E:\wamp\www\dededln\back(d ...

  2. Python系列之入门篇——MYSQL

    Python系列之入门篇--MYSQL 简介 python提供了两种mysql api, 一是MySQL-python(不支持python3),二是PyMYSQL(支持python2和python3) ...

  3. IO 异常:The Network Adapter could not establish the connection 怎么解决

    IO 异常:The Network Adapter could not establish the connection 怎么解决

  4. This is probably because there is no OLE editor registered against the type of file you were trying to open.

    Reason: This is probably because there is no OLE editor registered against the type of file you were ...

  5. Spring切面优先级

    项目中有两个切面,这两个切面都作用于同一个方法,哪个先执行哪个后执行呢,所以要定义一个切面的优先级 import java.util.Arrays; import org.aspectj.lang.J ...

  6. 两个arduino的通信

    两个arduino板进行串口通讯实验 (-- ::)转载▼ 标签: 杂谈 购得两块arduino板子,想试试其通讯能力,于是写下如是程序,居然没有打麻烦,奇怪! 接线:两个板子各用电池供电,将两块板子 ...

  7. awk匹配某一段内容,打印第一段

    要求: awk 文本在文本中搜索abc搜到后再从搜到的那一行开始一直输出后面的行,直到某一行含有bcd就停止 测试文本: [root@localhost]# cat awktest sadfj sdj ...

  8. 【转】 C++易混知识点4: 自己编写一个智能指针(Reference Counting)学习auto_ptr和reference counting

    这篇文章建大的介绍了如何编写一个智能指针. 介绍: 什么是智能指针?答案想必大家都知道,智能指针的目的就是更好的管理好内存和动态分配的资源,智能指针是一个智能的指针,顾名思义,他可以帮助我们管理内存. ...

  9. MySQL相关命令与备份

    不加任何参数直接备份 mysqldump -uroot zabbix >/opt/zabbix.bak.sql 恢复,这样恢复时需要自已创建表 mysql -uroot < zabbix. ...

  10. samephore()信号量跨线程通信

    samephore1: #include <stdio.h> #include <stdlib.h> #include <Windows.h> ] = " ...