矩阵快速幂(入门) 学习笔记hdu1005, hdu1575, hdu1757
矩阵快速幂是基于普通的快速幂的一种扩展,如果不知道的快速幂的请参见http://www.cnblogs.com/Howe-Young/p/4097277.html。二进制这个东西太神奇了,好多优秀的算法都跟他有关系,这里所说的矩阵快速幂就是把原来普通快速幂的数换成了矩阵而已,只不过重载了一下运算符*就可以了,也就是矩阵的乘法, 当然也可以写成函数,标题中的这三个题都是关于矩阵快速幂的基础题。拿来练习练习熟悉矩阵快速幂,然后再做比较难点的,其实矩阵快速幂比较难的是构造矩阵。下面还是那题目直接说话:
hdu1575:
题目大意:求一个矩阵k此方之后主对角线上的元素之和对9973取模
这个题是矩阵快速幂的裸题,直接用就行了。下面是代码
- #include<iostream>
- #include <string.h>
- #include <stdio.h>
- #include <algorithm>
- using namespace std;
- const int N = ;
- const int mod = ;
- struct Matrix{
- int a[N][N];
- };
- int n;
- Matrix operator * (Matrix t1, Matrix t2)//重载运算符 *
- {
- Matrix c;
- memset(c.a, , sizeof(c.a));
- //矩阵乘法
- for (int k = ; k < n; k++)
- {
- for (int i = ; i < n; i++)
- {
- if (t1.a[i][k] <= )
- continue;
- for (int j = ; j < n; j++)
- {
- if (t2.a[k][j] <= )
- continue;
- c.a[i][j] = (c.a[i][j] + t1.a[i][k] * t2.a[k][j]) % mod;
- }
- }
- }
- return c;
- }
- //重载^运算符
- Matrix operator ^ (Matrix t, int k)
- {
- Matrix c;
- memset(c.a, , sizeof(c.a));
- //初始化矩阵c为单位阵
- for (int i = ; i < n; i++)
- {
- c.a[i][i] = ;
- }
- //这里用到快速幂
- for (; k; k >>= )
- {
- if (k & )
- c = c * t;
- t = t * t;
- }
- return c;
- }
- int main()
- {
- int T, k;
- cin >> T;
- while (T--)
- {
- cin >> n >> k;
- Matrix t1, t2;
- for (int i = ; i < n; i++)
- {
- for (int j = ; j < n; j++)
- cin >> t1.a[i][j];
- }
- t2 = t1 ^ k;
- int res = ;
- for (int i = ; i < n; i++)
- res = (res + t2.a[i][i]) % mod;
- cout << res << endl;
- }
- return ;
- }
hdu1005:
题目大意:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
给你A, B和n让你求f(n)是多少
这个题就需要稍微构造一下矩阵了
这样的话要求F(n)的话,只需要对求出来F(n-1)就行了,对应的F(n-1)要求出F(n-2),所以题目给了F(1)和F(2),所以乘以他前面的系数矩阵就为【F(3), F(2)】T,再接着成系数矩阵就为【F(4),F(3)】T所以要求F(n)只需要对系数矩阵进行n-2次幂就行了,然后最后要求的结果就是矩阵的第一行第一列的结果,代码如下
- #include<iostream>
- #include <cstring>
- #include <cstdio>
- #include <algorithm>
- using namespace std;
- const int N = ;
- const int mod = ;
- struct Matrix
- {
- int mat[N][N];
- };
- //矩阵乘法(函数的形式)
- Matrix Multi(Matrix a, Matrix b)
- {
- Matrix c;
- memset(c.mat, , sizeof(c.mat));
- for (int i = ; i < N; i++)
- {
- for (int j = ; j < N; j++)
- {
- for (int k = ; k < N; k++)
- c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % mod;
- }
- }
- return c;
- }
- //矩阵快速幂 (函数形式)
- Matrix quickMatrixPower(Matrix a, int k)
- {
- Matrix t;
- memset(t.mat, , sizeof(t.mat));
- for (int i = ; i < N; i++)
- t.mat[i][i] = ;
- //快速幂
- while (k)
- {
- if (k & )
- t = Multi(t, a);
- a = Multi(a, a);
- k >>= ;
- }
- return t;
- }
- int main()
- {
- long long a, b, n;
- while (cin >> a >> b >> n && (a + b + n))
- {
- Matrix t;
- //初始化系数矩阵
- t.mat[][] = a;
- t.mat[][] = b;
- t.mat[][] = ;
- t.mat[][] = ;
- if (n >= )
- {
- t = quickMatrixPower(t, n - );
- printf("%d\n", (t.mat[][] + t.mat[][]) % mod);
- }
- else
- {
- printf("%lld\n", n);
- }
- }
- return ;
- }
hdu1757
题目大意:
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .
Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
这个关键还是在于构造矩阵,因为给递推式了,所以矩阵还是比价好构造的,下图是构造的矩阵
推到过程类似于1005,不再赘述,代码如下:
- #include<iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- using namespace std;
- const int ori[][] = {, , , , , , , , , };
- struct Matrix
- {
- int str[][];
- };
- int m;
- //矩阵乘法
- Matrix operator * (Matrix a, Matrix b)
- {
- Matrix c;
- memset(c.str, , sizeof(c.str));
- for (int i = ; i < ; i++)
- {
- for (int j = ; j < ; j++)
- {
- for (int k = ; k < ; k++)
- c.str[i][j] = (c.str[i][j] + a.str[i][k] * b.str[k][j]) % m;
- }
- }
- return c;
- }
- //矩阵快速幂
- Matrix power (Matrix a, int k)
- {
- Matrix c;
- memset(c.str, , sizeof(c.str));
- for (int i = ; i < ; i++)
- c.str[i][i] = ;
- while (k)
- {
- if (k & )
- c = c * a;
- a = a * a;
- k >>= ;
- }
- return c;
- }
- //最后一步的矩阵乘法
- int Multi(Matrix a)
- {
- Matrix c;
- memset(c.str, , sizeof(c.str));
- for (int i = ; i < ; i++)
- {
- for (int j = ; j < ; j++)
- {
- for (int k = ; k < ; k++)
- {
- c.str[i][j] = (c.str[i][j] + ori[i][k] * a.str[k][j]) % m;
- }
- }
- }
- return c.str[][] % m;
- }
- int main()
- {
- int k;
- while (cin >> k >> m)
- {
- Matrix t;
- memset(t.str, , sizeof(t.str));
- for (int i = ; i < ; i++)
- {
- cin >> t.str[i][];
- for (int j = ; j < ; j++)
- if (i + == j)
- t.str[i][j] = ;
- }
- if (k >= )
- {
- t = power(t, k - );
- printf("%d\n", Multi(t));
- }
- else
- {
- printf("%d\n", k);
- }
- }
- return ;
- }
矩阵快速幂(入门) 学习笔记hdu1005, hdu1575, hdu1757的更多相关文章
- POJ_Fibonacci POJ_3070(矩阵快速幂入门题,附上自己写的矩阵模板)
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10521 Accepted: 7477 Descri ...
- HDU 1575 Tr A 【矩阵经典2 矩阵快速幂入门】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1575 Tr A Time Limit: 1000/1000 MS (Java/Others) Me ...
- hdu 1575 Tr A (矩阵快速幂入门题)
题目 先上一个链接:十个利用矩阵乘法解决的经典题目 这个题目和第二个类似 由于矩阵乘法具有结合律,因此A^4 = A * A * A * A = (A*A) * (A*A) = A^2 * A^2.我 ...
- hdu 2604 Queuing(矩阵快速幂乘法)
Problem Description Queues and Priority Queues are data structures which are known to most computer ...
- UVA10870—Recurrences(简单矩阵快速幂)
题目链接:https://vjudge.net/problem/UVA-10870 题目意思: 给出a1,a2,a3,a4,a5………………ad,然后算下面这个递推式子,简单的矩阵快速幂,裸题,但是第 ...
- HDU1005 找规律 or 循环点 or 矩阵快速幂
http://acm.hdu.edu.cn/showproblem.php?pid=1005 1.一开始就注意到了n的数据范围 <=100 000 000,但是还是用普通的循环做的,自然TLE了 ...
- 【原创】SpringBoot & SpringCloud 快速入门学习笔记(完整示例)
[原创]SpringBoot & SpringCloud 快速入门学习笔记(完整示例) 1月前在系统的学习SpringBoot和SpringCloud,同时整理了快速入门示例,方便能针对每个知 ...
- NOI ONLINE 入门组 魔法 矩阵快速幂
做了这道题我才发现NOI入门组!=NOIP普及组 题目链接 https://www.luogu.com.cn/problem/P6190 题意 给出一张有向图,你有K次机会可以反转一条边的边权,即让它 ...
- Sass简单、快速上手_Sass快速入门学习笔记总结
Sass是世界上最成熟.稳定和强大的专业级css扩展语言 ,除了Sass是css的一种预处理器语言,类似的语言还有Less,Stylus等. 这篇文章关于Sass快速入门学习笔记. 资源网站大全 ht ...
随机推荐
- terminal命令
新建一个文件并写入内容: echo hello world > a.txt (每次echo都会重写文件) 新建文件: touch a.txt 新建目录: mkdir work 用vim打开文件 ...
- c#中使用easyUI的DataGrid组件
前台页面 html <table id="dg"> </table> JavaScript $("#dg").datagrid({ wi ...
- select 下拉菜单Option对象使用add(elements,index)方法动态添加
原生js 的add函数为下拉菜单增加选项 1.object.add(oElement [, iIndex]) index 可选参数:指定元素放置所在的索引号,整形值.如果没有指定值,将添加到集合的最后 ...
- Js仿弹框
收藏一个简单实用的JS弹框,通过隐藏和显示div来实现,代码来自脚本之家! <html> <head> <title> LIGHTBOX EXAMPLE </ ...
- Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2)
Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2) 上一节主要介绍了SolrCloud分布式索引的整体流程图以及索引链的实现,那么本节开始将分别介绍三个索引过程即LogUpdat ...
- 转:7个鲜为人知却超实用的PHP函数
PHP have lots of built-in functions, and most developers know many of them. But a few functions are ...
- PCB模擬設計接地的指導原則
接地無疑是系統設計中最為棘手的問題之一.盡管它的概念相對比較簡單,實施起來卻很復雜,遺憾的是,它沒有一個簡明扼要可以用詳細步驟描述的方法來保證取得良好效果,但如果在某些細節上處理不當,可能會導致令人頭 ...
- Spring Data Elasticsearch
项目清单 elasticsearch服务下载包括其中插件和分词 http://download.csdn.net/detail/u014201191/8809619 项目源码 资源文件 ...
- 14.4.4 Redo Log Buffer
14.4.4 Redo Log Buffer redo log buffer 是内存区域持有数据被写入到redo log. Redo log buffer size 是通过 innodb_log_bu ...
- 双向队列 STL
题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列的队尾同时也是队首:两头都可以做出队,入队的操作.现在给你一系列的操作,请输出最后队列的状态:命令格式:LIN X X表示一个整数,命 ...