链接: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. MVC系列学习(五)-传递数据 与 接收数据

    1.控制器向视图传递数据 a.使用ViewData b.使用ViewBag c.使用Model 方式二: d.使用TempData 2.为什么在控制器中设置了一些属性,在视图中可以接受 3.Actio ...

  2. java_基础知识_字符串练习题_计算两个字符串的最长公共字串长度

    package tek; Java算法——求出两个字符串的最长公共字符串 /** * @Title: 问题:有两个字符串str1和str2,求出两个字符串中最长公共字符串. * @author 匹夫( ...

  3. STL之set篇

    insert为插入.set_intersection求交集,set_union求并集,是属于algorithm里的函数. 例题有 PAT甲级1063 #include<iostream> ...

  4. html5——伸缩比例

    基本概念 1.父盒子设置了伸缩属性,子盒子设置伸缩比例 2.以上设置完之后子盒子会按照比例分布在父盒子中 3.当设置伸缩比例时默认会按照x轴方向分配,因为默认情况下伸缩布局主轴方向是x轴方向 4.设置 ...

  5. 【译】x86程序员手册17-第6章保护

    Chapter 6 Protection 第六章 保护 6.1 Why Protection? 为什么要保护? The purpose of the protection features of th ...

  6. 关于Qt 报QDomDocument: No such file or directory错误解决办法

    肯定是没有找到相关的路径,这时候只需要在.pro文件中加入便好了,比如我要用到读写xml的一些头文件,则需要在.pro中加入如下代码: 就可以正常引用了.

  7. python 将中文转拼音后填充到url做参数并写入excel

    闲着没事写了个小工具,将中文转拼音后填充到url做参数并写如excel 一.先看下演示,是个什么东西 二.代码 代码用到一个中文转拼音的库,库是网上下的,稍微做了下修改,已经找不原来下载的地址了,然后 ...

  8. Python操作数据库及hashlib模块

    一.hashlib模块 hashlib模块,主要用于加密相关的操作,在python3的版本里,代替了md5和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA51 ...

  9. 解决richfaces自带的jquery

    项目里有个有史以来让人头疼的问题,就是前端的richfaces框架自带有jquery插件,而且好像总是在最后才加载,导致前面自己加载好的jquery版本的框架以及应用到jquery的其他前端框架生成的 ...

  10. jenkins环境搭建(Windows)

    1.下载并解压Tomcat Tomcat官方网站:http://tomcat.apache.org/ 下载并解压,解压后的目录结构如下: 2.下载并安装适合自己电脑系统的 jenkins Jenkin ...