Reading comprehension

这个不难找出递推式f[n]=f[n−1]+2f[n−2]+1f[n] = f[n - 1] + 2f[n - 2] + 1f[n]=f[n−1]+2f[n−2]+1。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;ll n, mod;struct matrix {ll a[3][3];
};matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 0; i < 3; i++) {for(int j = 0; j < 3; j++) {ans.a[i][j] = 0;for(int k = 0; k < 3; k++) {ans.a[i][j] = (ans.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % mod) % mod;}}}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);while(scanf("%lld %lld", &n, &mod) != EOF && (n + mod)) {if(n <= 2) {if(n == 1) printf("%d\n", 1 % mod);else printf("%d\n", 2 % mod);continue;}matrix ans = {2, 1, 1,0, 0, 0,0, 0, 0};matrix a = {1, 1, 0,2, 0, 0, 1, 0, 1};n -= 2;while(n) {if(n & 1) ans = ans * a;a = a * a;n >>= 1;}printf("%lld\n", ans.a[0][0]);}return 0;
}

233 Matrix

这里直接写出构造的矩阵了。
A=[a00a10a20…a(n−1)0an010…0…]A =\left[\begin{matrix} a_{00}&a_{10}&a_{20}\dots a_{(n - 1)0}&a_{n0}&1\\ 0& \dots\\ 0& \dots\\ \end{matrix}\right] A=⎣⎡​a00​00​a10​……​a20​…a(n−1)0​an0​1⎦⎤​
整体来说就是一个(n+2)×(n+2)(n + 2) \times(n + 2)(n+2)×(n+2)的矩阵吧。
B=[101010…10100011…110001…110…333…331]B =\left[ \begin{matrix} 10&10&10 \dots 10&10&0\\ 0&1&1 \dots 1&1&0\\ 0&0&1\dots1&1&0\\ \dots\\ 3&3&3\dots3&3&1\\ \end{matrix} \right] B=⎣⎢⎢⎢⎢⎡​1000…3​10103​10…101…11…13…3​10113​0001​⎦⎥⎥⎥⎥⎤​
同样的也是一个(n+2)×(n+2)(n + 2) \times(n + 2)(n+2)×(n+2)的矩阵。

我们个a00a_{00}a00​初始化为232323,这个时候A×BA \times BA×B发现AAA中的元素会变成第二列的,所以这里就形成了一个递推式了,只要跑一跑矩阵快速幂即可。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;const int mod = 10000007;int n, m;struct matrix {ll a[15][15];void init() {memset(a, 0, sizeof a);}
};matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {ans.a[i][j] = 0;for(int k = 0; k < n; k++) {ans.a[i][j] = (ans.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % mod) % mod;}}}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);while(scanf("%d %d", &n, &m) != EOF) {matrix ans, a;ans.init(), a.init();for(int i = 1; i <= n; i++) scanf("%lld", &ans.a[0][i]);ans.a[0][0] = 23, ans.a[0][n + 1] = 1;for(int i = 0; i <= n; i++) {a.a[0][i] = 10;a.a[n + 1][i] = 3;}a.a[n + 1][n + 1] = 1;for(int i = 1; i <= n; i++) {for(int j = i; j <= n; j++) {a.a[i][j] = 1;}}n += 2;while(m) {if(m & 1) ans = ans * a;a = a * a;m >>= 1;}printf("%lld\n", ans.a[0][n - 2]);}return 0;
}

B. Jzzhu and Sequences

裸题fn=fn−1−fn−2f_n = f_{n - 1} - f_{n - 2}fn​=fn−1​−fn−2​。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;const int mod = 1e9 + 7;int n = 2, m;struct matrix {ll a[2][2];void init() {memset(a, 0, sizeof a);}
};matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {ans.a[i][j] = 0;for(int k = 0; k < n; k++) {ans.a[i][j] = (ans.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % mod) % mod;}}}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);ll x, y, n;scanf("%lld %lld %lld", &x, &y, &n);if(n <= 2) {if(n == 1) printf("%d\n", (x % mod + mod) % mod);else printf("%d\n", (y % mod + mod) % mod);return 0;}matrix ans = {y, x, 0, 0};matrix a = {1, 1,-1, 0};n -= 2;while(n) {if(n & 1) ans = ans * a;a = a * a;n >>= 1;}printf("%lld", (ans.a[0][0] % mod + mod) % mod);return 0;
}

M斐波那契数列

这是个乘法的递推式,显然乘法可以变成指数相加,所以还是一个矩阵快速幂,统计最后一项有多少个A0,A1A_0,A_1A0​,A1​即可。

当然矩阵中的取模得用费马小定理。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;const int mod = 1000000006;int n = 4, m;struct matrix {ll a[4][4];void init() {memset(a, 0, sizeof a);}
};matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {ans.a[i][j] = 0;for(int k = 0; k < n; k++) {ans.a[i][j] = (ans.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % mod) % mod;}}}return ans;
}ll quick_pow(ll a, int n) {ll ans = 1;const int mod = 1e9 + 7;while(n) {if(n & 1) ans = ans * a % mod;a = a * a % mod;n >>= 1;}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);ll x, y, n;while(scanf("%lld %lld %lld", &x, &y, &n) != EOF) {const int mod = 1e9 + 7;if(n <= 1) {if(n == 0) {printf("%lld\n", x % mod);}else {printf("%lld\n", y % mod);}continue;}matrix ans = {1, 0, 0, 1,0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0};matrix a = {1, 0, 1, 0,0, 1, 0, 1,1, 0, 0, 0,0, 1, 0, 0};n -= 1;while(n) {if(n & 1) ans = ans * a;a = a * a;n >>= 1;}ll res = 1ll * quick_pow(x, ans.a[0][1]) * quick_pow(y, ans.a[0][0]) % mod;printf("%lld\n", res);}return 0;
}

So Easy!

共轭矩阵构造的经典题了。

假设An=(a+b)n,Bn=(a−b)nA_n = (a + \sqrt b) ^n,B_n = (a - \sqrt b) ^nAn​=(a+b​)n,Bn​=(a−b​)n,一定有An+BnA_n + B_nAn​+Bn​是个有理数

并且有Bn<1B_n < 1Bn​<1,所以有⌈Sn⌉=An+Bn\lceil S_n \rceil = A_n + B_n⌈Sn​⌉=An​+Bn​

2aSn=((a+b)n+(a−b)n)((a+b)+(a−b))=Sn+1+(a2−b)Sn−12aS_n = ((a + \sqrt b) ^n + (a - \sqrt b) ^n)((a + \sqrt b) + (a - \sqrt b)) = S_{n + 1} +(a ^2 - b)S_{n - 1}2aSn​=((a+b​)n+(a−b​)n)((a+b​)+(a−b​))=Sn+1​+(a2−b)Sn−1​

得到Sn=2aSn−1+(b−a2)Sn−2S_n = 2aS_{n - 1} +(b - a ^ 2)S_{n - 2}Sn​=2aSn−1​+(b−a2)Sn−2​,于是递推式就得到了进行矩阵快速幂即可。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;// const int mod = 1000000006;ll n = 2, mod;struct matrix {ll a[2][2];void init() {memset(a, 0, sizeof a);}
};matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {ans.a[i][j] = 0;for(int k = 0; k < n; k++) {ans.a[i][j] = (ans.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % mod) % mod;}}}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);ll a, b, n;while(scanf("%lld %lld %lld %lld", &a, &b, &n, &mod) != EOF) {ll a1 = 2ll * a % mod, a2 = 2ll * (a * a % mod + b) % mod;if(n <= 2) {if(n == 1) printf("%lld\n", a1);else printf("%lld\n", a2);continue;}n -= 2;matrix ans = {a2, a1, 0, 0};matrix fat = {2ll * a % mod, 1,((b - a * a % mod) % mod + mod) % mod, 0};while(n) {if(n & 1) ans = ans * fat;fat = fat * fat;n >>= 1;}printf("%lld\n", ans.a[0][0]);}return 0;
}

Problem of Precision

这道题目是向下取整,跟上一道题目一样构造,唯一的不同就是Sn=An+Bn−1S_n = A_n + B_n - 1Sn​=An​+Bn​−1,所以我们还是按照SnS_nSn​递推,最后在答案上减一即可。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;const int mod = 1024;int n = 2;struct matrix {ll a[2][2];void init() {memset(a, 0, sizeof a);}
};matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {ans.a[i][j] = 0;for(int k = 0; k < n; k++) {ans.a[i][j] = (ans.a[i][j] + 1ll * a.a[i][k] * b.a[k][j] % mod) % mod;}}}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int T;scanf("%d", &T);while(T--) {ll n;scanf("%lld", &n);ll a1 = 10, a2 = 98;if(n <= 2) {if(n == 1) printf("%lld\n", (a1 - 1) % mod);else printf("%lld\n", (a2 - 1) % mod);continue;}n -= 2;matrix ans = {a2, a1,0, 0};matrix fat = {10, 1,1023, 0};while(n) {if(n & 1) ans = ans * fat;fat = fat * fat;n >>= 1;}printf("%lld\n", (ans.a[0][0] - 1 + mod) % mod);}return 0;
}

C. Partial Sums

由于递推矩阵的特殊关系,所以可以转化为1×n1 \times n1×n的矩阵递推,最后达到n2log(n)n ^ 2log(n)n2log(n)的复杂度。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;const int N = 2e3 + 10, mod = 1e9 + 7;int n, k;struct matrix {ll a[N];
};matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 1; i <= n; i++) {ans.a[i] = 0;for(int j = 1; j <= i; j++) {ans.a[i] = (ans.a[i] + a.a[j] * b.a[i - j + 1] % mod) % mod;}}return ans;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);scanf("%d %d", &n, &k);matrix ans, a;for(int i = 1; i <= n; i++) {scanf("%d", &ans.a[i]);a.a[i] = 1;}while(k) {if(k & 1) ans = ans * a;a = a * a;k >>= 1;}for(int i = 1; i <= n; i++) {printf("%lld%c", ans.a[i], i == n ? '\n' : ' ');}return 0;
}

Fast Matrix Calculation

ABn2=A(BA)n2−1BAB^{n^2} = A(BA)^{n^2 - 1}BABn2=A(BA)n2−1B,转化为k×kk \times kk×k的矩阵快速幂,这样就可以保证不超时了。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;
const double eps = 1e-7;const int N = 1e3 + 10, mod = 6;int n, m;struct matrix {ll a[6][6];void init() {memset(a, 0, sizeof a);}
}c;struct Matrix {ll a[N][N];
}a, b, Ans1, Ans2;matrix operator * (matrix a, matrix b) {matrix ans;for(int i = 0; i < m; i++) {for(int j = 0; j < m; j++) {ans.a[i][j] = 0;for(int k = 0; k < m; k++) {ans.a[i][j] = (ans.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;}}}return ans;
}matrix mult() {matrix ans;for(int i = 0; i < m; i++) {for(int j = 0; j < m; j++) {ans.a[i][j] = 0;for(int k = 0; k < n; k++) {ans.a[i][j] = (ans.a[i][j] + b.a[i][k] * a.a[k][j] % mod) % mod;}}}return ans;
}int main() {// freopen("in.txt", "r", stdin);   // freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);while(scanf("%d %d", &n, &m) && (n + m)) {for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {scanf("%lld", &a.a[i][j]);}}for(int i = 0; i < m; i++) {for(int j = 0; j < n; j++) {scanf("%lld", &b.a[i][j]);}}c = mult();matrix ans;ans.init();for(int i = 0; i < m; i++) ans.a[i][i] = 1;int n1 = n * n - 1;while(n1) {if(n1 & 1) ans = ans * c;c = c * c;n1 >>= 1;}for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {Ans1.a[i][j] = 0;for(int k = 0; k < m; k++) {Ans1.a[i][j] = (Ans1.a[i][j] + a.a[i][k] * ans.a[k][j] % mod) % mod;}}}for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {Ans2.a[i][j] = 0;for(int k = 0; k < m; k++) {Ans2.a[i][j] = (Ans2.a[i][j] + Ans1.a[i][k] * b.a[k][j] % mod) % mod;}}}int res = 0;for(int i = 0; i < n; i++) {for(int j = 0; j < n; j++) {res += Ans2.a[i][j];}}printf("%d\n", res);}return 0;
}

矩阵快速幂各类题型总结(一般,共轭,1 * n, 矩阵简化)相关推荐

  1. 线性代数 —— 矩阵快速幂

    [概述] 矩阵快速幂利用矩阵的乘法与整数快速幂的结合,能够快速的算出 n 阶方阵 A 的 M 次幂 A^b,其结果仍是一个矩阵,无具体含义,在信息学竞赛中,矩阵快速幂常用于求解线性递推关系. 关于矩阵 ...

  2. python【数据结构与算法】快速幂and矩阵快速幂取模(看不懂你来打我)

    文章目录 1 解释快速幂 2 代码(这里就不考虑指数为小于0的情况了) 3 下面是矩阵快速幂,区别只是底数换成了矩阵 1 解释快速幂 传统的幂运算,是对底数进行连乘,时间复杂度为o(n),例如:2^1 ...

  3. hdu5015 矩阵快速幂233(好题)

    题意:       给你一个(n+1)*(m+1)的矩阵mat,然后给你mat[0][1] = 233 ,mat[0][2] = 2333,mat[0][3] = 23333...,然后输入mat[1 ...

  4. 矩阵快速幂---BestCoder Round#8 1002

    当要求递推数列的第n项且n很大时,怎么快速求得第n项呢? 可以用矩阵快速幂来加速计算. 我们可以用矩阵来表示数列递推公式 比如fibonacci数列 可以表示为 [f(n)   f(n-1)] = [ ...

  5. 又见斐波那契~矩阵快速幂入门题

    链接:https://www.nowcoder.com/acm/contest/105/G 来源:牛客网 题目描述 这是一个加强版的斐波那契数列. 给定递推式 求F(n)的值,由于这个值可能太大,请对 ...

  6. 算法分类整理+模板①:矩阵快速幂

    一直有一个想法,感觉自己很多基础算法不是很扎实,想要找个机会写一些算法的整理,顺便自己总结一些实用的模板. 最近偶然在训练赛中连续做了2道思维+矩阵快速幂的题目,碰巧有时间,就以矩阵快速幂作为这个系列 ...

  7. 矩阵快速幂的学习(系统的学习)

    学习博客:https://www.cnblogs.com/cmmdc/p/6936196.html https://www.cnblogs.com/yan-boy/archive/2012/11/29 ...

  8. 快速幂或者矩阵快速幂

    快速幂或者矩阵快速幂在算大指数次方时是很高效的,他的基本原理是二进制,下面的A可以是一个数也可以是一个矩阵(本文特指方阵),若是数就是快速幂算法,若是矩阵就是矩阵快速幂算法,用c++只需把矩阵设成一个 ...

  9. 浅谈矩阵 矩阵快速幂 动态dp 矩阵求逆

    文章目录 1 矩阵 1.1 矩阵乘法 1.2 单位矩阵 1.3 矩阵乘法的结合律 1.4 矩阵快速幂 1.5 矩阵快速幂的应用 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 ...

最新文章

  1. Nginx做前端代理时缓存与否的性能差别
  2. java正则表达式及api_Java魔法堂:深入正则表达式API
  3. 10-10数组的介绍
  4. PHP svn开发环境搭建,手把手搭建WAMP+PHP+SVN开发环境,wampsvn_PHP教程
  5. 深入理解javascript 中的 delete(转)
  6. 我想成为计算机专业第一,我对计算机专业学生的忠告。
  7. 可伸缩架构-面向增长应用的高可用
  8. php mysql安装_搭建PHP环境中的MySQL配置
  9. Redis和MongoDB通讯协议简介
  10. java8中的接口与时间操作
  11. 【OpenCV】角点检测:Harris角点及Shi-Tomasi角点检测
  12. 三人抢答器逻辑电路图_数字电路3人抢答器实验报告.doc
  13. keil更改黑色背景颜色
  14. C语言练习-[1005]温度转换
  15. 普通人如何使用ChatGPT接单挣钱-第一弹
  16. 数据监控难点之实时监测
  17. 如何看计算机接口类型,怎么看自己电脑cpu的接口类型
  18. suppo aaa 0.75-php,fastsupport-cn
  19. 优化总结:有哪些APP启动提速方法?
  20. SpringBoot项目中ModelMapper配置以及使用

热门文章

  1. 一维数组和二维数组的区别_数组指针和指针数组的区别
  2. 统信uos系统考试题_148款!富士通及旗下晟拓品牌系列打印机适配统信UOS
  3. 10张劲爆眼球的科学动图
  4. 又一中国机械狗来了:腾跃呼啦圈、原地起跳顶飞皮球,还能自主充电
  5. 中国式创新技术“步态识别”终于来临,你大胆地走两步,我就知道你是谁
  6. 抓取手机https_python爬虫入门02:教你通过 Fiddler 进行手机抓包
  7. android 带弧形背景,[Android日常]绘制弧形渐变背景
  8. Java JSON对象怎么遍历_Java遍历JsonObject对象
  9. ncl 添加点shp文件_气象编程 | NCL高效快速精准提取不规则区域内的格点数据
  10. java static new_java静态类new的对象是否能被回收?