当前位置: 首页 > news >正文

矩阵(板子)

文章目录

  • 一、前言
  • 二、算法
      • <1>P3390 (【模板】矩阵快速幂)
      • <2> P1939 (矩阵加速(数列))
      • <3> P1306 (斐波那契公约数)
  • 三、总结


一、前言

//一些矩阵乘法


二、算法

<1>P3390 (【模板】矩阵快速幂)

题解:
给定一个矩阵,求它的k次方
因为矩阵本身的乘法运算满足交换律和结合律,所以思考发现也应该满足快速幂的二的幂次相乘的规律。
对应一般的快速幂,写一个矩阵快速幂的函数,重新定义乘法,注意传参问题即可。
代码:

#include<bits/stdc++.h>using namespace std;
#define int long longconst int mod = 1e9+7;
const int N = 110;
int n,k;
int a[N][N];int qpow(int base,int power) {int res = 1;while(power) {if(power & 1) res = res*base%mod;base = base*base%mod;power >>= 1;}return res;
}//一般快速幂void chen(int ra[][N],int rb[][N]) {int ls[N][N];for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {for (int lk = 1; lk <= n; lk++) {ls[i][j] += (ra[i][lk]*rb[lk][j]%mod);ls[i][j] %= mod;//cout << ra[i][lk] << ' ' << rb[lk][j] << endl;}//cout << i << '/' << j << endl;}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {ra[i][j] = ls[i][j];ls[i][j] = 0;}}
}//矩阵乘法方式,ra数组会被传回去int ans[N][N];
void qpow_jz(int power) {while(power) {if(power & 1) chen(ans,a);chen(a,a);power >>= 1;}return ;
}//求矩阵a的power次方void solve() {cin >> n >> k;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> a[i][j];}}for (int i = 1; i <= n; i++) {ans[i][i] = 1;}//单位矩阵qpow_jz(k);for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cout << ans[i][j] << ' ';}cout << endl;}
}signed main() {ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int _ = 1;//cin >> _;while(_--) solve();
}

<2> P1939 (矩阵加速(数列))

题解:
给了一个f数组的递推式,要求第n项,n高达2e9.
真是没想到跟矩阵有什么关系,看了题解发现可以考虑整体递推,这样就是一个不断相乘的过程。
【f[3],f[2],f[1]】(竖着摆放)
f[4] = f[3]+f[1]
f[3] = f[3]
f[2] = f[2]
根据矩阵相乘的规律,可以得到矩阵A
[1,0,1
1,0,0
0,1,0]
这是一次递推式,如果需要多次递推,也就是矩阵A的快速幂,快速幂n次之后发现ans[2][1]就是所需要的答案。

代码:

#include<bits/stdc++.h>using namespace std;
#define int long longconst int mod = 1e9+7;
const int N = 5;
int n = 3;
int k;
int a[N][N];int qpow(int base,int power) {int res = 1;while(power) {if(power & 1) res = res*base%mod;base = base*base%mod;power >>= 1;}return res;
}//一般快速幂void chen(int ra[][N],int rb[][N]) {int ls[N][N];memset(ls,0,sizeof ls);for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {for (int lk = 1; lk <= n; lk++) {ls[i][j] += (ra[i][lk]*rb[lk][j]%mod);ls[i][j] %= mod;//cout << ra[i][lk] << ' ' << rb[lk][j] << endl;}//cout << i << '/' << j << endl;//cout << ls[i][j] << endl;}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {ra[i][j] = ls[i][j];ls[i][j] = 0;}}
}int ans[N][N];
void qpow_jz(int power) {//求矩阵a的power次方while(power) {if(power & 1) chen(ans,a);chen(a,a);power >>= 1;}return ;
}void solve() {cin >> k;if(k <= 3) {cout << 1 << endl;return ;}memset(a,0,sizeof a);memset(ans,0,sizeof a);a[1][1] = a[1][3] = a[2][1] = a[3][2] = 1;for (int i = 1; i <= n; i++) {ans[i][i] = 1;}//单位1qpow_jz(k);cout << ans[2][1] << endl;}signed main() {ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int _ = 1;cin >> _;while(_--) solve();
}

<3> P1306 (斐波那契公约数)

题解:
主要需要考虑到一开始的n就会超过1e8,所以直接mod 会有误差,经过一系列推算,发现先求公约数再算斐波那契数和原本所要求的是一样的,所以计算出转移矩阵后用矩阵快速幂即可。
代码:

#include<bits/stdc++.h>using namespace std;
#define int long longconst int mod = 1e8;
const int N = 5;
int n = 2;
int k;
int a[N][N];int qpow(int base,int power) {int res = 1;while(power) {if(power & 1) res = res*base%mod;base = base*base%mod;power >>= 1;}return res;
}//一般快速幂void chen(int ra[][N],int rb[][N]) {int ls[N][N];memset(ls,0,sizeof ls);for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {for (int lk = 1; lk <= n; lk++) {ls[i][j] += (ra[i][lk]*rb[lk][j]%mod);ls[i][j] %= mod;//cout << ra[i][lk] << ' ' << rb[lk][j] << endl;}//cout << i << '/' << j << endl;//cout << ls[i][j] << endl;}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {ra[i][j] = ls[i][j];ls[i][j] = 0;}}
}int ans[N][N];
void qpow_jz(int power) {//求矩阵a的power次方while(power) {if(power & 1) chen(ans,a);chen(a,a);power >>= 1;}return ;
}int gcd(int x,int y) {return y ? gcd(y,x%y):x;
}int rx,ry;void solve() {cin >> rx >> ry;int k = gcd(rx,ry);if(k <= 2) {if(rx == 0) rx = 1;else ry = 1;return ;}memset(a,0,sizeof a);memset(ans,0,sizeof a);a[1][1] = a[1][2] = a[2][1] = 1;for (int i = 1; i <= n; i++) {ans[i][i] = 1;}//单位1qpow_jz(k);
//    for(int i = 1; i <= n; i++) {
//        for (int j = 1; j <= n; j++) {
//            cout << ans[i][j] << ' ';
//        }cout << endl;
//    }cout << ans[2][1] << endl;
}signed main() {ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int _ = 1;// cin >> _;while(_--) solve();
}

三、总结

http://www.dtcms.com/a/560878.html

相关文章:

  • 防火墙的内容补充
  • C++类和对象(下):初始化列表
  • 建筑工程找活网站wordpress文章新窗口
  • 沭阳城乡建设局网站做外国网站百度搜到
  • java-接口适配器模式 jsk8 接口默认实现
  • program.cs文件详解
  • 深圳市企业网站seo做东西的网站有那些
  • 京东测开面经整理(日常实习)
  • 大文件上传
  • 做ppt找图片网站推广网发布的信息准确吗
  • Linux内核POSIX文件锁机制深度解析
  • 从“CPU 烧开水“到优雅暂停:Go 里 sync.Cond 的正确打开方式
  • 大模型系列——Excel数据治理新思路:引入智能体实现自动纠错【Python+Agent】
  • Pyppeteer 使用教程
  • React性能优化:useMemo vs useCallback
  • Onsemi展示了垂直GaN-on-GaN半导体
  • 专业机票网站建设禅城区建设局网站
  • Java 日志演进:一文读懂主流框架
  • 第3章 变量与数据类型
  • pyside6 qt 事件循环
  • Secertpad搭建
  • 吞吐量、延迟、内存:深入理解垃圾回收的“三元悖论”
  • List接口和常用方法
  • 计算机一级考试网站怎么做用织梦系统做网站产权
  • Java 数据结构第二十八期:反射、枚举以及 lambda 表达式
  • Linux 磁盘分区与系统监控完全指南
  • 是普通网站地图好还是rss地图好一点网站建设申请费用
  • 使用Graphics2D创建滑块验证码
  • Flutter provide框架内部实现原理刨析
  • 关于rpm,yum,apt