POJ 3233 Matrix Power Series(矩阵快速幂)
题面
Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K
Total Submissions: 19338 Accepted: 8161
Description
Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.
Input
The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing n nonnegative integers below 32,768, giving A’s elements in row-major order.
Output
Output the elements of S modulo m in the same way as A is given.
Sample Input
2 2 4
0 1
1 1
Sample Output
1 2
2 3
思路
这题暴力做肯定没救,我们需要优化。第一种做法是直接去递推矩阵关系,然后构造矩阵进行一个简化的快速幂,这样我们只需要操作一遍快速幂就好了。第二种做法的话,我们可以选择一个二分加速,求法类似于等比数列的二分求法,从数列中项开始提取公因式,不断递归就可以快速求得数列的和了,当然这里我们要把数列当成数字来处理,道理也是一样。所以,矩阵快速幂,包括一些数学题,当它的暴力做法很明显,而数据量又很大的时候,我们要尝试从数据量上去考虑如何加速。这题的话很容易想到二分,另外我们也需要对式子进行数学分析,看看是不是存在一些性质,可以让我们快速求解。
代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=65;
int n,mod,k;
struct Matrix {
int maze[maxn][maxn];
Matrix () {
memset (maze,0,sizeof (maze));
}
};
Matrix mul (Matrix a,Matrix b) {
Matrix ans;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++) {
for (int k=1;k<=n;k++)
(ans.maze[i][j]+=(a.maze[i][k]*b.maze[k][j])%mod)%=mod;
}
return ans;
}
Matrix fast_pow (Matrix a,int k) {
Matrix ans;
memset (ans.maze,0,sizeof (ans.maze));
for (int i=1;i<=n;i++) ans.maze[i][i]=1;
while (k) {
if (k&1) ans=mul (ans,a);
a=mul (a,a);
k>>=1;
}
return ans;
}
int main () {
while (cin>>n>>k>>mod) {
Matrix a,b,c;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++) {
cin>>a.maze[i][j+n];
b.maze[i+n][j+n]=a.maze[i][j+n];
}
for (int i=1;i<=n;i++) {
b.maze[i][i]=1;
b.maze[i+n][i]=1;
}
n=n*2;
c=mul (a,fast_pow (b,k));
for (int i=1;i<=n/2;i++)
for (int j=1;j<=n/2;j++) {
if (j==n/2) cout<<c.maze[i][j]<<endl;
else cout<<c.maze[i][j]<<" ";
}
}
return 0;
}
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 35;
struct mat
{
int a[MAXN][MAXN];
mat()
{
memset(a,0,sizeof(a));
}
};
mat m;
mat I;
int n,k,mod;
mat add(mat m1,mat m2)
{
mat ans;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans.a[i][j]=(m1.a[i][j]+m2.a[i][j])%mod;
return ans;
}
mat mul(mat m1,mat m2)
{
mat ans;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
ans.a[i][j]=(ans.a[i][j]+m1.a[i][k]*m2.a[k][j])%mod;
return ans;
}
mat quickmul(mat m,int k)
{
mat ans;
for(int i=1;i<=n;i++) ans.a[i][i] = 1;
while(k)
{
if(k&1) ans=mul(ans,m);
m=mul(m,m);
k>>=1;
}
return ans;
}
mat sum(int k)//等比求和
{
if(k==1) return m;
mat t=sum(k/2);
mat ans;
if(k&1)
{
mat cur=quickmul(m,k/2+1);
ans=add(mul(add(I,cur),t),cur);
}
else
{
mat cur=quickmul(m,k/2);
ans=mul(add(I,cur),t);
}
return ans;
}
void print(mat m)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
printf("%d%c",m.a[i][j],j==n? '\n':' ');
}
int main()
{
while(~scanf("%d%d%d",&n,&k,&mod))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&m.a[i][j]);
I.a[i][j]=(i==j);
}
mat ans=sum(k);
print(ans);
}
return 0;
}
原文地址:https://www.cnblogs.com/hhlya/p/13287240.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 面试题系列第4篇:重写了equals方法,为什么还要重写hashCode方法?
- LPC17XX之SSP0/1接口
- 宝塔打开ssl面板后打不开登录界面的解决方法
- 记录一下vuedraggable clone的坑,获取数据
- Go语言|go version命令的高级用法
- 基于 git flow + gitlab 协作开发:01
- 嵌入式之GPS
- 嵌入式之一款GPRS模块的应用
- 如何设计一个JavaScript插件系统
- C语言之字段类型应用的技巧
- 分布式秒杀实战之订单数据分表
- SourceInsight4.0的使用
- 基于operator sdk编写k8s自定义资源管理应用
- CAN总线之ISO15765协议
- Linux文本编辑命令