链接: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. day03_12/13/2016_bean属性的设置之setter方法注入

  2. 海量文本信息查Top-k

    问题描述: 有1千万条短信,一条一行,有重复.在5分钟之内,找出重复出现的前10条. 方案一: 1.分组进行边扫描边建散列表.建立哈希表,使用头,尾和中间随便两个字节作为Hash Code, 插入到H ...

  3. [转]Linux中set,env和export这三个命令的区别

    转自:http://www.2cto.com/os/201306/223758.html Linux中set,env和export这三个命令的区别   set命令显示当前shell的变量,包括当前用户 ...

  4. 更新换代之requests库

    好久不更新博客了... 之前的博文都是通过urllib2进行http访问,接下来我要说一个利器啊!requests模块,无法用语言对他进行赞扬了,需要的,有兴趣的,可以去了解下,移步官方中文文档: R ...

  5. Sql Server 如何解决多并发情况下,出现的多个相同ID数据

    在数据库中单独创建一张表,保存当前存储状态,“存储过程”  设置访问条件root初始值为“0” 如果root值不为0的时候就不可访问并进行相关操作. 在事务执行前将root值设置为1,事务结束后将ro ...

  6. Android通过透明度设置背景变暗

    变暗 WindowManager.LayoutParams lp=getWindow().getAttributes(); lp.alpha=0.3f; getWindow().addFlags(Wi ...

  7. 编写高质量的js之恰当选用if和switch

    switch结构中存在很多限制,存在这些限制的主要目的是提高多重分支结构的执行效率.因此,如果能够使用switch结构,就不要选择if结构. 无论是使用if结构,还是使用switch结构,应该确保下面 ...

  8. dubbo之优雅停机

    优雅停机 Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果用户使用 kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才 ...

  9. CAD在网页中如何得到用户自定义事件的参数?

    主要用到函数说明: _DMxDrawX::CustomEventParam 得到用户自定义事件的参数. js代码实现如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  10. 数据结构与算法(6) -- heap

    binary heap就是一种complete binary tree(完全二叉树).也就是说,整棵binary tree除了最底层的叶节点之外,都是满的.而最底层的叶节点由左至右又不得有空隙. 以上 ...