ACM 矩阵题目整理
先从最基础的矩阵快速幂加速递推开始。
HDU 1005 Number Sequence
|f[n-2],f[n-1]|* |0 B| =|f[n-1], B*f[n-2]+A*f[n-1]|=|f[n-1],f[n]|
|1 A|
建立矩阵如上然后利用快速幂求解即可。答案是mat[0][1]。
#include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<queue> #include<cmath> #include<set> #include<string> #define INF 1000000005 #define LL long long using namespace std; ; struct Matrix { int n,m; int a[MAXN][MAXN]; ,) { n=x; m=y; memset(a,,sizeof(a)); } Matrix operator * (const Matrix &b)const { Matrix tmp; tmp.clear(n,b.m); ; i<n; ++i) ; j<b.m; ++j) ; k<m; ++k) { tmp.a[i][j]+=a[i][k]*b.a[k][j]; tmp.a[i][j]%=; } return tmp; } }; Matrix quickPow(Matrix mat,int n) { Matrix res; res.clear(,); res.a[][]=res.a[][]=; while(n) { ) res=res*mat; mat=mat*mat; n=n>>; } return res; } int main() { int A,B,n; while(scanf("%d%d%d",&A,&B,&n)!=EOF) { if(!A&&!B&&!n) break; ||n==) { puts("); continue; } Matrix mat; mat.clear(,); mat.a[][]=; mat.a[][]=B; mat.a[][]=; mat.a[][]=A; Matrix f; f.clear(,); f.a[][]=; f.a[][]=; n-=; Matrix s=f*quickPow(mat,n); printf(][])%); } ; }
HDU 4920 Matrix multiplication
矩阵乘法,直接算会超时。由于是模3,所以0很多,也就是稀疏矩阵。可以优化。
参见下文:http://www.cnblogs.com/jackiesteed/articles/2021604.html
#include<iostream> #include<vector> #include<map> #include<cmath> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<string> #define LL long long using namespace std; ][],B[][]; ][]; int n; int main() { int n; while(scanf("%d",&n)!=EOF) { ; i<=n; ++i) ; j<=n; ++j) { scanf("%d",&A[i][j]); A[i][j]%=; } ; i<=n; ++i) ; j<=n; ++j) { scanf("%d",&B[i][j]); B[i][j]%=; } memset(C,,sizeof(C)); ; i<=n; ++i) ; j<=n; ++j) { ) continue; ; k<=n; ++k) C[i][k]+=A[i][j]*B[j][k]; } ; i<=n; ++i) { ; j<=n; ++j) ) printf(); ); printf("\n"); } } ; }
HDU 1575 Tr A
求矩阵的迹。直接快速幂即可。
#include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<queue> #include<cmath> #include<set> #include<string> #define INF 1000000005 #define LL long long using namespace std; ; struct Matrix { int n,m; int a[MAXN][MAXN]; ,) { n=x; m=y; memset(a,,sizeof(a)); } Matrix operator * (const Matrix &b)const { Matrix tmp; tmp.clear(n,b.m); ; i<n; ++i) ; j<b.m; ++j) { ; k<b.m; ++k) { ==a[i][j]) continue;//优化! tmp.a[i][k]+=a[i][j]*b.a[j][k]; tmp.a[i][k]%=; } } return tmp; } void setOne(int x) { clear(x,x); ; i<x; ++i) a[i][i]=; } }; Matrix one; Matrix quickPow(Matrix mat,int n) { Matrix res=one; while(n) { ) res=res*mat; mat=mat*mat; n=n>>; } return res; } int main() { int T; scanf("%d",&T); while(T--){ int n,k; scanf("%d%d",&n,&k); one.setOne(n); Matrix mat; mat.clear(n,n); ;i<n;++i) ;j<n;++j) scanf("%d",&mat.a[i][j]); mat=quickPow(mat,k); ; ;i<n;++i) { ans+=mat.a[i][i]; ans%=; } printf("%d\n",ans); } ; }
HDU 1757 A Simple Math Problem
一个简单的递推,建立矩阵后,快速幂。
#include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<queue> #include<cmath> #include<set> #include<string> #define INF 1000000005 #define LL long long using namespace std; ; int M; struct Matrix { int n,m; int a[MAXN][MAXN]; ,) { n=x; m=y; memset(a,,sizeof(a)); } Matrix operator * (const Matrix &b)const { Matrix tmp; tmp.clear(n,b.m); ; i<n; ++i) ; j<b.m; ++j) { ; k<b.m; ++k) { ==a[i][j]) continue;//优化! tmp.a[i][k]+=a[i][j]*b.a[j][k]; tmp.a[i][k]%=M; } } return tmp; } void setOne(int x) { clear(x,x); ; i<x; ++i) a[i][i]=; } }; Matrix one; Matrix quickPow(Matrix mat,int n) { Matrix res=one; while(n) { ) res=res*mat; mat=mat*mat; n=n>>; } return res; } int main() { int k; one.setOne(); while(scanf("%d%d",&k,&M)!=EOF) { Matrix mat; mat.clear(,); ; i<; ++i) mat.a[i+][i]=; ; i<; ++i) scanf(-i][]); ) printf("%d\n",k%M); else { Matrix f; f.clear(,); ; i<; ++i) f.a[][i]=i; k-=; f=f*quickPow(mat,k); printf(][]); } } ; }
UVa 10870 Recurrences
与上面类型相似的题,建立矩阵,再快速幂加速。注意会超int。
#include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<queue> #include<cmath> #include<set> #include<string> #define INF 1000000005 #define LL long long using namespace std; ; int M; struct Matrix { int n,m; LL a[MAXN][MAXN]; ,) { n=x; m=y; memset(a,,sizeof(a)); } Matrix operator * (const Matrix &b)const { Matrix tmp; tmp.clear(n,b.m); ; i<n; ++i) ; j<b.m; ++j) { ; k<b.m; ++k) { ==a[i][j]) continue;//优化! tmp.a[i][k]+=a[i][j]*b.a[j][k]; tmp.a[i][k]%=M; } } return tmp; } void setOne(int x) { clear(x,x); ; i<x; ++i) a[i][i]=; } }; Matrix one; Matrix quickPow(Matrix mat,LL n) { Matrix res=one; while(n) { ) res=res*mat; mat=mat*mat; n=n>>; } return res; } int main() { int d,n; while(scanf("%d%d%d",&d,&n,&M)!=EOF) { if(!d&&!n&&!M) break; one.setOne(d); Matrix mat; mat.clear(d,d); ; i<d; ++i) mat.a[i+][i]=; ; i<d; ++i) scanf(-i][d-]); Matrix f; f.clear(,d); ; i<d; ++i) scanf(][i]); if(n<=d) printf(][n-]%M); else { n-=d; f=f*quickPow(mat,n); printf(][d-]%M); } } ; }
POJ 3734 Blocks
递推+矩阵快速幂。
设计状态的时候要考虑所有可能的情况,保证无重复无遗漏,再考虑转移。最后用矩阵加速。
#include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<queue> #include<cmath> #include<set> #include<string> #define INF 1000000005 #define LL long long using namespace std; ; ; struct Matrix { int n,m; int a[MAXN][MAXN]; Matrix(,):n(x),m(y) { memset(a,,sizeof(a)); } ,) { n=x; m=y; memset(a,,sizeof(a)); } Matrix operator * (const Matrix &b)const { Matrix tmp; tmp.clear(n,b.m); ; i<n; ++i) ; j<b.m; ++j) { ; k<b.m; ++k) { ==a[i][j]) continue;//ÓÅ»¯£¡ tmp.a[i][k]+=a[i][j]*b.a[j][k]; tmp.a[i][k]%=M; } } return tmp; } void setOne(int x) { clear(x,x); ; i<x; ++i) a[i][i]=; } }; Matrix one; Matrix quickPow(Matrix mat,int n) { Matrix res=one; while(n) { ) res=res*mat; mat=mat*mat; n=n>>; } return res; } int main() { one.setOne(); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); Matrix mat(,); mat.a[][]=,mat.a[][]=,mat.a[][]=; mat.a[][]=,mat.a[][]=,mat.a[][]=; mat.a[][]=,mat.a[][]=,mat.a[][]=; Matrix f(,); f.a[][]=; Matrix ans=f*quickPow(mat,n); printf(][]); } ; }
POJ 3420 Quad Tiling
这个题的关键是在求递推式。
设dp[i]表示填满前i个方块的种数。那么从dp[i-1]转移有1种情况,从dp[i-2]转移有4种情况,在之后从dp[i-a],如果a是奇数有2种情况,a是偶数有3种情况。
这样最终化简得dp[i]=dp[i-1]+5dp[i-2]+dp[i-3]-dp[i-4]
#include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<queue> #include<cmath> #include<set> #include<string> #define INF 1000000005 #define LL long long using namespace std; ; int M; struct Matrix { int n,m; int a[MAXN][MAXN]; Matrix(,):n(x),m(y) { memset(a,,sizeof(a)); } ,) { n=x; m=y; memset(a,,sizeof(a)); } Matrix operator * (const Matrix &b)const { Matrix tmp; tmp.clear(n,b.m); ; i<n; ++i) ; j<b.m; ++j) { ; k<b.m; ++k) { ==a[i][j]) continue;//优化 tmp.a[i][k]+=a[i][j]*b.a[j][k]; tmp.a[i][k]%=M; } } return tmp; } void setOne(int x) { clear(x,x); ; i<x; ++i) a[i][i]=; } }; Matrix one; Matrix quickPow(Matrix mat,int n) { Matrix res=one; ) { ) res=res*mat; mat=mat*mat; n=n>>; } return res; } int main() { int n; one.setOne(); while(scanf("%d%d",&n,&M)!=EOF) { if(!n&&!M) break; Matrix mat(,); ; i<; ++i) mat.a[i+][i]=; mat.a[][]=-,mat.a[][]=,mat.a[][]=,mat.a[][]=; Matrix f(,); f.a[][]=,f.a[][]=,f.a[][]=,f.a[][]=; ) printf(][n]%M); else { n-=; Matrix s=f*quickPow(mat,n); printf(][]); } } ; }
ZOJ 3690 Choosing number
a[i]表示第i个人选小于等于k的数字的合法种数,a[i]=(k-1)*a[i]+k*b[i]
b[i]表示第i个人选大于等于k的数字的合法种数,b[i]=(m-k)*a[i]+(m-k)*b[i]
a[0]=0,b[0]=1,答案是a[n]+b[n]
建立矩阵快速幂计算即可。
#include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include<queue> #include<cmath> #include<set> #include<string> #define INF 1000000005 #define LL long long using namespace std; ; ; struct Matrix { int n,m; LL a[MAXN][MAXN]; Matrix(,):n(x),m(y) { memset(a,,sizeof(a)); } ,) { n=x; m=y; memset(a,,sizeof(a)); } Matrix operator * (const Matrix &b)const { Matrix tmp; tmp.clear(n,b.m); ; i<n; ++i) ; j<m; ++j) { ; k<b.m; ++k) { ==a[i][j]) continue;//优化! tmp.a[i][k]+=a[i][j]*b.a[j][k]; tmp.a[i][k]%=M; } } return tmp; } void setOne(int x) { clear(x,x); ; i<x; ++i) a[i][i]=; } }; Matrix one; Matrix quickPow(Matrix mat,int n) { Matrix res=one; while(n) { ) res=res*mat; mat=mat*mat; n=n>>; } return res; } int main() { int n,m,k; one.setOne(); while(scanf("%d%d%d",&n,&m,&k)!=EOF) { Matrix mat(,); mat.a[][]=k-,mat.a[][]=k; mat.a[][]=m-k,mat.a[][]=m-k; Matrix f(,); f.a[][]=,f.a[][]=; Matrix s=quickPow(mat,n)*f; printf(][]+s.a[][])%M); } ; }
ACM 矩阵题目整理的更多相关文章
- ACM 字符串 题目整理
AC自动机 UVa 11468 Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...
- Noip往年题目整理
Noip往年题目整理 张炳琪 一.历年题目 按时间倒序排序 年份 T1知识点 T2知识点 T3知识点 得分 总体 2016day1 模拟 Lca,树上差分 期望dp 144 挺难的一套题目,偏思维难度 ...
- NOIp初赛题目整理
NOIp初赛题目整理 这个 blog 用来整理扶苏准备第一轮 csp 时所做的与 csp 没 有 关 系 的历年 noip-J/S 初赛题目,记录了一些我从不知道的细碎知识点,还有一些憨憨题目,不定期 ...
- ACM 暴力搜索题 题目整理
UVa 129 Krypton Factor 注意输出格式,比较坑爹. 每次要进行处理去掉容易的串,统计困难串的个数. #include<iostream> #include<vec ...
- ACM - 动态规划专题 题目整理
CodeForces 429B Working out 预处理出从四个顶点到某个位置的最大权值,再枚举相遇点,相遇的时候只有两种情况,取最优解即可. #include<iostream> ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 第八届蓝桥杯c/c++省赛题目整理
第一题 标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都 ...
- ACM金牌选手整理的【LeetCode刷题顺序】
算法和数据结构知识点图 首先,了解算法和数据结构有哪些知识点,在后面的学习中有 大局观,对学习和刷题十分有帮助. 下面是我花了一天时间花的算法和数据结构的知识结构,大家可以看看. 后面是为大家 精心挑 ...
- 内工大acm校赛--整理代码
题目:小明搜到一行无缩进无换行代码,请帮小明整理代码.无for语句和case语句,而且只有一个主函数.你只要控制注意“:”“{”“}”这三个符号带来的缩进和换行效果就行. Input: 输入只有一行, ...
随机推荐
- 红字差评系列1.第K小数
[题目分析] 二分答案?smg,我太弱了 //不开longlong wa到挺了 #include <cstdio> #include <cstring> #include &l ...
- SQL触发器实例
SQL触发器实例讲解(本文是来自百度文库) 备注:本人建了一个站特价汇,我想记录每个商品的点击量,然后按照点击量来牌名商品,想要提高效率,所以必须得用触发器,下面是本人在百度文库中的找到的学习资料,分 ...
- 【Unity3D游戏开发】NGUI之多分辨率下完美分布式协同开发 (五)
NGUI多分辨率下完美分布式协同开发:不同分辨率下相对于屏幕坐标的Perfab数据不再丢失 NGUI多分辨率下完美分布式协同开发不同分辨率下相对于屏幕坐标的Perfab数据不再丢失 开发问题 原因分析 ...
- C++11在时空性能方面的改进
C++11在时空性能方面的改进 这篇我们聊聊C++11在时间和空间上的改进点: 主要包括以下方面: 新增的高效容器:array.forward_list以及unordered containers: ...
- powerdesinger中建立一个表后,出现Existence of index的警告
可以不检查 Existence of index 这项,也就没有这个警告错误了!意思是说没有给表建立索引,而一个表一般至少要有一个索引,这是一个警告,不用的话对执行没有影响~ 转载:http://bl ...
- 0050 Linux VIM 命令
1. 模式切换 vim的模式 $ vi filename 进入normal 模式,这是命令模式,用于执行大多数常用的编辑命令,不能输入 敲i 进入 insert 模式,这是正常的编辑模式,按Esc ...
- angular router-ui
将模块注入到控制器中的方法: 1.export module 2.在router中resolve解决: 2.1 resolve中直接return值 /*ngInject*/ worker : 'hi' ...
- Load Runner11录制脚本出现乱码的解决方法
方法一: 1.录制的脚本出现乱码 Go to Vugen -> Tools -> Recording Options -> Advancedb) Check the option ...
- Tomcat下使用war包发布项目
Tomcat下使用war包发布项目 转自<Tomcat下使用war包发布项目 >,地址:http://blog.csdn.net/wy818/article/details/7240294 ...
- 计算机上没有找到was服务
控制面板->程序->打开或关闭windows功能,勾选Microsoft .net framework下的两项.