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: 输入只有一行, ...
随机推荐
- android界面横屏和竖屏的切换
关于android横屏和竖屏的切换网上给了很多种.但是有些介绍的方法都是在android旧版本上. 我现在把握用到的情况写下来用于备忘: android 版本:4.0 - 4.4 要求:android ...
- VS2012下基本类型大小
- hadoop运维经验
0.优化:http://dongxicheng.org/mapreduce/hadoop-optimization-0/ http://dongxicheng.org/mapreduce/hadoop ...
- minicom 使用教程
因为现在电脑基本不配备串行接口,所以,usb转串口成为硬件调试时的必然选择.目前知道的,PL2303的驱动是有的,在dev下的名称是ttyUSB#. minicom,tkterm都是linux下应用比 ...
- c++ 指针常量,常量指针
当const遇到指针 一般来说,const修饰指针可以分为下面的集中情况. 描述 例子 含义 备注 const在*的左边 const int *b=&a; int const *b=& ...
- Sprint(第一天11.14)
Sprint1第一阶段 1.类名:软件工程-第一阶段 2.时间:11.14-11.23 3.选题内容:点餐系统 4.团队博客地址:http://www.cnblogs.com/iamCarson/ 团 ...
- 开源.NET FTP组件edtFTPnet 用法
edtFTPnet官方网站:http://www.enterprisedt.com/products/edtftpnet/ 目前最新版本为2.2.3,下载后在bin目录中找到edtFTPnet.dll ...
- ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)
最近在做一个电商项目,其中商品搜索中出现一个奇怪的现象,根据某个字段排序的时候会出现商品数量减少的情况.按照一般路要么查不出来,要么正常显示,为什么增加了按照销量排序就会出现查询结果减少的情况. 查了 ...
- Windows里面的hosts文件
一.什么是Hosts文件? hosts文件是一个用于储存计算机网络中各节点信息的计算机文件.这个文件负责将主机名映射到相应的IP地址.hosts文件通常用于补充或取代网络中DNS的功能.和DNS不同的 ...
- 【转载】CSS 伪类-:before和:after
:before和:after的作用就是在指定的元素内容(而不是元素本身)之前或者之后插入一个包含content属性指定内容的行内元素,最基本的用法如下: #example:before { conte ...