POJ 3150 Cellular Automaton
来源:互联网 发布:sql常用查询语句 编辑:程序博客网 时间:2024/05/22 05:30
矩阵的题就是这么伤脑筋啊~~ sad……
题目大意:
一个环上有n个数,定义一种操作将它和它距离小于d的数加和再模m。每次操作刷新所有数。问k次之后都将变成什么数?
解题思路:
矩阵快速幂加速递推。
按照正常思路第i次操作是基于第i-1次操作完成的,也就是说要完成第i次操作需要先完成第i-1次。
但是用于矩阵之后可以直接推出第i次与第一次之间是什么关系。
这个矩阵是可以通过矩阵快速幂得出的。取模也是顺带的~
如果你注意关系矩阵的建立的话,你会发现这么一个规律。对于d=1来说:
b^1 =
[1, 1, 0, 0, 1]
[1, 1, 1, 0, 0]
[0, 1, 1, 1, 0]
[0, 0, 1, 1, 1]
[1, 0, 0, 1, 1]
b^2 =
[3, 2, 1, 1, 2]
[2, 3, 2, 1, 1]
[1, 2, 3, 2, 1]
[1, 1, 2, 3, 2]
[2, 1, 1, 2, 3]
b^3 =
[7, 6, 4, 4, 6]
[6, 7, 6, 4, 4]
[4, 6, 7, 6, 4]
[4, 4, 6, 7, 6]
[6, 4, 4, 6, 7]
b^4 =
[19, 17, 14, 14, 17]
[17, 19, 17, 14, 14]
[14, 17, 19, 17, 14]
[14, 14, 17, 19, 17]
[17, 14, 14, 17, 19]
也就是说我们只需要存第一行就行了。每次矩阵乘法也只需要得出第一行就行了。
下面是代码:
#include <set>#include <map>#include <queue>#include <math.h>#include <vector>#include <string>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>#define eps 1e-7#define pi acos(-1.0)#define inf 107374182#define inf64 1152921504606846976#define lc l,m,tr<<1#define rc m + 1,r,tr<<1|1#define iabs(x) ((x) > 0 ? (x) : -(x))#define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE))#define clearall(A, X) memset(A, X, sizeof(A))#define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE))#define memcopyall(A, X) memcpy(A , X ,sizeof(X))#define max( x, y ) ( ((x) > (y)) ? (x) : (y) )#define min( x, y ) ( ((x) < (y)) ? (x) : (y) )using namespace std;struct node{ long long matrix[505];}a,temp;int n,m,d,k;node does(node a,node b){ node c; clearall(c.matrix,0); int p; for(int i=0;i<n;i++) { p=(n-i)%n; for(int j=0;j<n;j++) { c.matrix[i]+=a.matrix[j]*b.matrix[p++]; if(p==n)p=0; } c.matrix[i]%=m; } return c;}void mul(int k){ clearall(temp.matrix,0); temp.matrix[0]=1; while(k) { if(k&1)temp=does(temp,a); a=does(a,a); k>>=1; }}int main(){ long long num[505],ans[505]; int p; while(scanf("%d%d%d%d",&n,&m,&d,&k)!=EOF) { clearall(ans,0); for(int i=0;i<n;i++) { scanf("%lld",&num[i]); } for(int i=0;i<n;i++) { if(i<=d||n-i<=d)a.matrix[i]=1; else a.matrix[i]=0; } mul(k); for(int i=0;i<n;i++) { if(i!=0)printf(" "); p=(n-i)%n; for(int j=0;j<n;j++) { ans[i]+=temp.matrix[p++]*num[j]; if(p==n)p=0; } printf("%lld",ans[i]%m); } puts(""); } return 0;}
0 0
- poj 3150 Cellular Automaton
- POJ 3150 Cellular Automaton
- poj 3150 Cellular Automaton
- POJ 3150 Cellular Automaton
- poj 3150 Cellular Automaton
- POJ 3150 Cellular Automaton
- POJ 3150 Cellular Automaton
- poj 3150 Cellular Automaton
- 【poj 3150】Cellular Automaton 矩阵
- POJ 3150 Cellular Automaton 笔记
- POJ 3150 Cellular Automaton 矩阵dp
- POJ 3150 Cellular Automaton(矩阵快速幂)
- poj 3150Cellular Automaton(矩阵快速幂)
- POJ Cellular Automaton
- Poj 3150/UVA 1386/UVALive 3704 Cellular Automaton 循环矩阵
- poj 3150 Cellular Automaton(矩阵快速幂)
- POJ 3150 Cellular Automaton --矩阵快速幂及优化
- POJ 3150 Cellular Automaton(矩阵快速幂)
- hdu 1698 Just a Hook(线段树的区间更新及求和)
- AIDL
- 云服务器-产品介绍
- Vision引擎中环境地形技术信息
- MySQL内置函数详细介绍
- POJ 3150 Cellular Automaton
- myeclipse JVM参数配置
- 边缘检测
- ZOJ1151 word reserve
- 2014黑帽大会揭露十大恐怖安全漏洞!
- Python中的datetime时间上的明天和七天之后的日期确定问题
- 利用结构体定义一个加法以及自定义输出
- MySQL预处理语句
- Activity与Service通信