链接: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. 【BZOJ3205_洛谷3638】[APIO2013]机器人(动态规划)

    题目: 洛谷3638 分析: 卡了一天的神题--(OrzJumpmelon) 首先预处理出从点\(p\)向\(d\)方向出发最终能到达的点\(nxt[p][d]\).这个可以直接记忆化搜索解决.如果出 ...

  2. flask web 表单验证 WTForms

    简介 WTForms 是一个flask集成框架,或者说是库,用于处理浏览器表单提交的数据,它在flask-WTF的基础上扩展并添加了一些随手可得的精巧帮助函数,这些函数将会是在flask里使用表单更加 ...

  3. MySQL的安装和启动

    一.MySQL各类安装方法的比较 在Linux系统下,MySQL有3种主要的安装方式,分别是:RPM安装.二进制安装.源码安装.三种安装方式的优缺点如下表所示:   RPM安装 二进制安装 源码安装 ...

  4. 下载谷歌地图封锁IP解决办法

    采用重新拨号,动态改变IP的方式.可以使用软件<易好用IP自动更换软件>

  5. react杂记

    React webpack+react (hello world) 项目结构: src: app.js main.js package.json webpack_dev_config.js 需要安装包 ...

  6. 右边根据左边的高度自动居中只需要两行CSS就可以完成

    右边根据左边的高度自动居中只需要两行CSS就可以完成 <style type="text/css" > div{ display: inline-block; vert ...

  7. 5.21leetcode练习

    目录 两数之和 题目 答案 整数反转 题目 思路及答案 回文数 题目 思路及答案 希望每天进步一点点 两数之和 题目 新手司机上路,光荣翻车,没想出来.借了别人的答案,自行领会 答案 整数反转 题目 ...

  8. day02 python

    列表: : 在[ ]内,可以存放多个任意类型的值: 并以逗号隔开. 一般用于存放学生的爱好:课堂的周期等等... 例如: 定义一个学生列表,可存放多个学生 list(['钱垚', '李小龙', '张全 ...

  9. Django - Ajax初识

    当需要在弹出的对话框中,做判断操作时,需要用到ajax 1.host.html <!DOCTYPE html><html lang="en"><hea ...

  10. Win32 线程同步

    Win32 线程同步 ## Win32线程同步 ### 1. 原子锁 ### 2. 临界区 {全局变量} CRITICAL_SECTION CS = {0}; // 定义并初始化临界区结构体变量 {线 ...