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: 输入只有一行, ...
随机推荐
- 开始跟踪Redis啦,开帖
随着NoSql的流行,对这方面的产品开始关注起来,之前一直只是看看.从昨天开始决定把Redis的实现机制啃下来,毕竟代码量也就2W行. 每天花时间看看,记录下成果. here we go.
- servlet定义
. 运行在服务器上的java类
- win7 64+python2.7.12安装numpy+scipy+matplotlib+scikit-learn
python包下载网址 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 1.已经安装python2.7.12,查看scripts里是否有pip.2.7.9版本以上 ...
- [课程设计]Scrum 2.6 多鱼点餐系统开发进度(下单一览页面-菜式添加功能实现)
Scrum 2.6 多鱼点餐系统开发进度 (下单一览页面-菜式添加功能实现) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题 ...
- 405 Method Not Allowed
今天在发布一个网站的时候遇到 标题上的问题,一直不明白是为何,刚开始以为是我的程序写的有问题,随即将项目发给同事来发布试试,在他的IIS上发布却没出现问题,一切正常,这可就怪了,于是想到了应该是IIS ...
- Number To Indian Rupee Words in Oracle Forms / Reports
Convert numbers to Indian Rupees format in Oracle Forms / Reports.Create the below mention function ...
- 利用backtrace和objdump进行分析挂掉的程序
转自:http://blog.csdn.net/hanchaoman/article/details/5583457 汇编不懂,先把方法记下来. glibc为我们提供了此类能够dump栈内容的函数簇, ...
- 怎样在excel中添加下拉列表框
用excel2013打开要编辑的工作表,例子是一个班级名单,可以看到政治面貌目前还没有填写 接着我们找一个空白处,依次写入政治面貌的可能选项: 群众.共青团员 然后选中“政治面貌”这一列,点击 ...
- ThinkPHP 3.2 模板中的Angularjs 的变量{{$first}} 无法被解析
ThinkPHP 3.2 模板中的Angularjs 的变量"{{$first}}" 无法被解析, 模板解析冲突,例如在angularjs 的变量"{{$first}}& ...
- Oracle数据库字段类型说明
目前Oracle 数据库大概有26个字段类型,大体分为六类,分别是字符串类型.数字数据类型.日期时间数据类型.大型对象(LOB)数据类型.RAW和LONG RAW数据类型.ROWID和UROWID数据 ...