poj 3150 Cellular Automaton
来源:互联网 发布:vbcf源码 编辑:程序博客网 时间:2024/05/12 11:00
点击打开poj 3150
思路: 矩阵快速幂
分析:
1 题目给定n个数每个数在0~m-1之内,题目规定两个数之间的距离为min(|i-j| , n-|i-j|)。现在给定d和k,表示做k次的变换,每一次变换过后每个数变成了一个新的数。这个新的数等于和它距离小于等于d的所有数的和%m
2 这题和之前做的两道题很像hdu2276 和 FZU1692,都是属于循环同构的问题
那么我们先来看一下每个数在做一次变换过后变成什么。因为要距离小于等于d,第一种|i-j| = d , 则j = i+d , 第二种情况n-|i-j| = d , 因此 j = n-d+i 。
第一个数等于 = num[1]+num[2]+....+num[d+1] + num[n-d+1]+...+num[n]
第二个数等于 = num[2]+....+num[d+2] + num[n-d+2]+...+num[n]
..............................................................................................................
3 因为这里的矩阵是循环同构的,因此我们只要求出第一行,剩下的我们就可以根据前一行推出。这样就把矩阵的乘法的复杂度降到了O(n^2)
代码:
/************************************************ * By: chenguolin * * Date: 2013-08-31 * * Address: http://blog.csdn.net/chenguolinblog * ************************************************/#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long int64;const int N = 505; int n , MOD , d , k;int arr[N];struct Matrix{ int64 mat[N][N]; Matrix operator*(const Matrix &m)const{ Matrix tmp; for(int i = 1 ; i <= n ; i++){ tmp.mat[1][i] = 0; for(int j = 1 ; j <= n ; j++) tmp.mat[1][i] += mat[1][j]*m.mat[j][i]%MOD; tmp.mat[1][i] %= MOD; } for(int i = 2 ; i <= n ; i++){ tmp.mat[i][1] = tmp.mat[i-1][n]; for(int j = 2 ; j <= n ; j++) tmp.mat[i][j] = tmp.mat[i-1][(j-1+n)%n]; } return tmp; }};void init(Matrix &m){ memset(m.mat , 0 , sizeof(m.mat)); for(int i = 1 ; i <= d+1 ; i++) m.mat[1][i] = 1; for(int i = n-d+1 ; i <= n ; i++) m.mat[1][i] = 1; for(int i = 2 ; i <= n ; i++){ m.mat[i][1] = m.mat[i-1][n]; for(int j = 2 ; j <= n ; j++) m.mat[i][j] = m.mat[i-1][(j-1+n)%n]; }}void Pow(Matrix &m){ Matrix ans; memset(ans.mat , 0 , sizeof(ans.mat)); for(int i = 1 ; i <= n ; i++) ans.mat[i][i] = 1; while(k){ if(k&1) ans = ans*m; k >>= 1; m = m*m; } for(int i = 1 ; i <= n ; i++){ int64 sum = 0; for(int j = 1 ; j <= n ; j++) sum += ans.mat[i][j]*arr[j]%MOD; if(i > 1) printf(" "); printf("%lld" , sum%MOD); } puts("");}int main(){ Matrix m; while(scanf("%d" , &n) != EOF){ scanf("%d%d%d" , &MOD , &d , &k); for(int i = 1 ; i <= n ; i++) scanf("%d" , &arr[i]); init(m); Pow(m); } return 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(矩阵快速幂)
- LeetCode:Add Binary
- To 黄践焜 jboss启动timeout <-- 薛洪
- 微信公众平台开发:进阶篇(在网页上添加分享到朋友圈、发送给好友、分享等按钮)
- lync 2010启用用户访问权限不够!
- JAX-RS
- poj 3150 Cellular Automaton
- 微信公众平台开发:进阶篇(如何获取微信公众原始号)
- Asp.net页面传参数给Silverlight
- 安装必备组件失败 Wmf2008R2
- POJ 3608 Bridge Across Islands (计算几何+三分)
- 黑马程序员——Java基础---多线程
- CSS样式优先级
- LeetCode:Jump Game
- JavaScript实用功能代码片段整理三