链接:http://poj.org/problem?id=3233

题意:给一个N*N的矩阵(N<=30),求S = A + A^2 + A^3 +
… + A^k(k<=10^9)。

思路:非常明显直接用矩阵高速幂暴力求和的方法复杂度O(klogk)。肯定会超时。我採用的是二分的方法, A + A^2 + A^3 + … + A^k=(1+A^(k/2)) *(A + A^2 + A^3 + … + A^(k/2))。这样就能够提出一个(1+A^(k/2)),假设k是奇数,单独处理A^k。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define maxn 35
#define maxm 35
#define INF 10005
#define eps 1e-8
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int k,mm;
struct Matrix
{
int n,m;
int a[maxn][maxm];
void init()
{
n=m=0;
memset(a,0,sizeof(a));
}
Matrix operator +(const Matrix &b) const
{
Matrix tmp;
tmp.n=n;
tmp.m=m;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
tmp.a[i][j]=a[i][j]+b.a[i][j];
tmp.a[i][j]=(tmp.a[i][j]+mm)%mm;
}
return tmp;
}
Matrix operator -(const Matrix &b) const
{
Matrix tmp;
tmp.n=n;
tmp.m=m;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
tmp.a[i][j]=a[i][j]-b.a[i][j];
return tmp;
}
Matrix operator *(const Matrix &b) const
{
Matrix tmp;
tmp.init();
tmp.n=n;
tmp.m=b.m;
for(int i=0; i<n; i++)
for(int j=0; j<b.m; j++)
for(int k=0; k<m; k++)
{
tmp.a[i][j]+=a[i][k]*b.a[k][j];
tmp.a[i][j]=(tmp.a[i][j]+mm)%mm;
} return tmp;
}
};//仅仅有当矩阵A的列数与矩阵B的行数相等时A×B才有意义
Matrix M_quick_pow(Matrix m,int k)
{
Matrix tmp;
tmp.n=m.n;
tmp.m=m.m;//m=n才干做高速幂
for(int i=0; i<tmp.n; i++)
{
for(int j=0; j<tmp.n; j++)
{
if(i==j)
tmp.a[i][j]=1;
else tmp.a[i][j]=0;
}
}
while(k)
{
if(k&1)
tmp=tmp*m;
k>>=1;
m=m*m;
}
return tmp;
}
int main()
{
Matrix A,ans,In,res;
while(~scanf("%d%d%d",&A.m,&k,&mm))
{
ans.init();
res.init();
res.m=res.n=ans.m=ans.n=In.m=In.n=A.n=A.m;
for(int i=0; i<In.m; i++)
{
In.a[i][i]=1;
res.a[i][i]=1;
}
for(int i=0; i<A.m; i++)
for(int j=0; j<A.n; j++)
{
scanf("%d",&A.a[i][j]);
A.a[i][j]%=mm;
}
while(k)
{
if(k==1)
{
res=res*A;
}
else
{
if(k%2)
ans=ans+res*M_quick_pow(A,k);
res=res*(In+M_quick_pow(A,k/2));
}
k/=2;
}
ans=ans+res;
for(int i=0; i<ans.m; i++)
{
for(int j=0; j<ans.m; j++)
{
if(j!=0)
printf(" ");
printf("%d",ans.a[i][j]);
}
printf("\n");
}
}
return 0;
}

POJ 3233 Matrix Power Series 二分+矩阵乘法的更多相关文章

  1. POJ 3233 Matrix Power Series (矩阵乘法)

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 11954   Accepted:  ...

  2. POJ 3233 Matrix Power Series(二分等比求和)

    Matrix Power Series [题目链接]Matrix Power Series [题目类型]二分等比求和 &题解: 这题我原来用vector写的,总是超时,不知道为什么,之后就改用 ...

  3. POJ 3233 Matrix Power Series(矩阵快速幂)

    Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 19338 Accepted: 8161 ...

  4. Poj 3233 Matrix Power Series(矩阵二分快速幂)

    题目链接:http://poj.org/problem?id=3233 解题报告:输入一个边长为n的矩阵A,然后输入一个k,要你求A + A^2 + A^3 + A^4 + A^5.......A^k ...

  5. POJ 3233 Matrix Power Series (矩阵+二分+二分)

    题目地址:http://poj.org/problem?id=3233 题意:给你一个矩阵A,让你求A+A^2+……+A^k模p的矩阵值 题解:我们知道求A^n我们可以用二分-矩阵快速幂来求,而 当k ...

  6. 题解报告:poj 3233 Matrix Power Series(矩阵快速幂)

    题目链接:http://poj.org/problem?id=3233 Description Given a n × n matrix A and a positive integer k, fin ...

  7. POJ 3233 Matrix Power Series (矩阵分块,递推)

    矩阵乘法是可以分块的,而且幂的和也是具有线性的. 不难得到 Si = Si-1+A*Ai-1,Ai = A*Ai-1.然后矩阵快速幂就可以了. /*************************** ...

  8. POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)

    题意:求S=(A+A^2+A^3+...+A^k)%m的和 方法一:二分求解S=A+A^2+...+A^k若k为奇数:S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+ ...

  9. POJ - 3233 Matrix Power Series (矩阵等比二分求和)

    Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + - + Ak. ...

随机推荐

  1. Android Framework 学习

    1. 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework面存一些资料待有空查看. 2.Android系统的层次如下: 3.项目目录简单分析如下: 4.telphony ...

  2. [转]linux之ps命令

    转自:http://www.cnblogs.com/peida/archive/2012/12/19/2824418.html Linux中的ps命令是Process Status的缩写.ps命令用来 ...

  3. Hadoop Hive概念学习系列之hive里如何显示当前数据库及传参(十九)

    这个小知识点,看似简单,用处极大. $ hive --hiveconf hive.cli.print.current.db=true $ hive --hiveconf hive.cli.print. ...

  4. Server Tomcat v8.0 Server at localhost failed to start 问题解决方法?

    bi编程jsp  servlet 第一个程序: HelloServlet 运行错误 404: 十月 28, 2017 11:25:14 上午 org.apache.tomcat.util.digest ...

  5. Perforce 的基本使用教程

    一.简介 P4是什么 二.基本使用方法 1.下载代码 下载最新代码 Get Latest Revision 下载指定commit代码 Get Revision 2. 检出代码 选择指定目录,右键 Ch ...

  6. 《Java编程的逻辑》第一部分 编程基础与二进制

  7. Monkey测试总结

    Monkey测试总结 1.什么是Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等), 实 ...

  8. 【SQLite】select into 语句

    sqlite不支持类似sqlserver中的select into 语法 在SQL Server中,我们要将一个表中的数据复制到一个新表中,可以这样写: SELECT * INTO newtable ...

  9. Tomcat服务器安装与第一个jsp网页程序

    1.安装tomcat服务器之前需要,先安装相应版本的jdk,个人理解Tomcat的大部分功能是使用了java的 jdk jar包的. jdk包下载方式网上可以查到 下载完后可以解压到一个指定目录,并在 ...

  10. SQL With As 用法Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介

    Sql 四大排名函数(ROW_NUMBER.RANK.DENSE_RANK.NTILE)简介   排名函数是Sql Server2005新增的功能,下面简单介绍一下他们各自的用法和区别.我们新建一张O ...