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+...+A^(k/2))+A^k
若k为偶数:
S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+A^(k/2))
也可以这么二分(其实和前面的差不多):
S(2n)=A+A^2+...+A^2n=(1+A^n)*(A+A^2+...+A^n)=(1+A^n)*S(n)
S(2n+1)=A+A^2+...+A^(2n+1)=A(1+A+..+A^2n)=A+(A+A^(n+1))*S(n)
一开始1900+ms,优化了下1500ms...还是太慢了。。。
本来在递归的时候,用快速幂计算A^(k/2)
后来改用直接递归的同时,计算A^(k/2),直接变成200ms左右。。。瞬间提升了10倍。。。
#include <iostream>
#include <cstdio>
#include <string.h> using namespace std;
const int maxn=;
int mod;
int n,k,m;
struct Matrix{
int m[maxn][maxn];
void init(){
memset(m,,sizeof(m));
}
void initE(){
memset(m,,sizeof(m));
for(int i=;i<n;i++)
m[i][i]=;
}
}A;
//重载+运算符
Matrix operator+(Matrix a,Matrix b){
Matrix c;
for(int i=;i<n;i++){
for(int j=;j<n;j++)
c.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
}
return c;
}
//重载*运算符
Matrix operator*(Matrix a,Matrix b){
Matrix c;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
c.m[i][j]=;
for(int k=;k<n;k++){
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod;
}
}
}
return c;
}
//矩阵快速幂
Matrix MquickPow(Matrix A,int b){
Matrix ret;
ret.initE();
while(b){
if(b&)
ret=ret*A;
A=A*A;
b=b>>;
}
return ret;
}
Matrix p;
Matrix dfs(Matrix A,int k){
if(k==){
p=A;
return A;
}
Matrix ret,ans;
ret=dfs(A,k/);
//Matrix p=MquickPow(A,k/2);如果用快速幂计算p=A^(k/2),则要1500ms,而直接在递归的时候同时计算p,则只要188ms。
if(k&){
//return ret+ret*p+p*p*A;
ans=ret+ret*p+p*p*A;
p=p*p*A;
}
else{
//return ret+ret*p;
ans=ret+ret*p;
p=p*p;
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&k,&m);
mod=m;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
scanf("%d",&A.m[i][j]);
}
}
Matrix ans;
ans=dfs(A,k);
for(int i=;i<n;i++){
for(int j=;j<n;j++){
printf("%d ",ans.m[i][j]);
}
printf("\n");
}
return ;
}
方法二:
688ms
http://blog.sina.com.cn/s/blog_9d5278a301015mbd.html
http://blog.csdn.net/wangjian8006/article/details/7868864
S=A(E+A(E+A(E+...A(E+A))))
这样就可以想,不妨构造一个矩阵T使得T*T,这样乘下去每次可以得到A*(A+E)+E
A 0 A^2 0 A^3 0
B= B^2= B^3=
E E A+E E A^2+A+E E
不难得出: A^(k+1) 0
B^(k+1)=
S(k) E
#include <iostream>
#include <iostream>
#include <cstdio>
#include <string.h> using namespace std;
const int maxn=;
int mod;
int n,k,m;
struct Matrix{
int m[maxn][maxn];
void init(){
memset(m,,sizeof(m));
}
void initE(){
memset(m,,sizeof(m));
for(int i=;i<n;i++)
m[i][i]=;
}
}A;
//重载+运算符
Matrix operator+(Matrix a,Matrix b){
Matrix c;
for(int i=;i<n;i++){
for(int j=;j<n;j++)
c.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
}
return c;
}
//重载*运算符
Matrix operator*(Matrix a,Matrix b){
Matrix c;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
c.m[i][j]=;
for(int k=;k<n;k++){
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod;
}
}
}
return c;
}
//矩阵快速幂
Matrix MquickPow(Matrix A,int b){
Matrix ret;
ret.initE();
while(b){
if(b&)
ret=ret*A;
A=A*A;
b=b>>;
}
return ret;
}
int main()
{
Matrix B;
B.init();
scanf("%d%d%d",&n,&k,&m);
mod=m;
for(int i=;i<n;i++){
for(int j=;j<n;j++){
scanf("%d",&B.m[i][j]);
}
B.m[i+n][i]=;
B.m[i+n][i+n]=;
}
n=n*;
Matrix ans=MquickPow(B,k+);
for(int i=n/;i<n;i++){
for(int j=;j<n/;j++){
if(i==j+n/)
ans.m[i][j]=(ans.m[i][j]-+mod)%mod; //对角线还要减去单位矩阵的1
printf("%d ",ans.m[i][j]);
}
printf("\n");
}
return ;
}
POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)的更多相关文章
- POJ 3233 Matrix Power Series 矩阵快速幂+二分求和
矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html 直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是 sum=A+A2+...+ ...
- POJ 3233 Matrix Power Series 矩阵快速幂
设S[k] = A + A^2 +````+A^k. 设矩阵T = A[1] 0 E E 这里的E为n*n单位方阵,0为n*n方阵 令A[k] = A ^ k 矩阵B[k] = A[k+1] S[k] ...
- POJ3233:Matrix Power Series(矩阵快速幂+二分)
http://poj.org/problem?id=3233 题目大意:给定矩阵A,求A + A^2 + A^3 + … + A^k的结果(两个矩阵相加就是对应位置分别相加).输出的数据mod m.k ...
- poj 3233 Matrix Power Series 矩阵求和
http://poj.org/problem?id=3233 题解 矩阵快速幂+二分等比数列求和 AC代码 #include <stdio.h> #include <math.h&g ...
- POJ 3233:Matrix Power Series 矩阵快速幂 乘积
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 18450 Accepted: ...
- poj 3233 Matrix Power Series(矩阵二分,高速幂)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 15739 Accepted: ...
- POJ3233 Matrix Power Series 矩阵快速幂 矩阵中的矩阵
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 27277 Accepted: ...
- Poj 3233 Matrix Power Series(矩阵乘法)
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Description Given a n × n matrix A and ...
- POJ 3233 Matrix Power Series(矩阵高速功率+二分法)
职务地址:POJ 3233 题目大意:给定矩阵A,求A + A^2 + A^3 + - + A^k的结果(两个矩阵相加就是相应位置分别相加).输出的数据mod m. k<=10^9. 这 ...
- POJ3233:Matrix Power Series(矩阵快速幂+递推式)
传送门 题意 给出n,m,k,求 \[\sum_{i=1}^kA^i\] A是矩阵 分析 我们首先会想到等比公式,然后得到这样一个式子: \[\frac{A^{k+1}-E}{A-E}\] 发现要用矩 ...
随机推荐
- ruby on rails 实战(二)
1,修改routes文件,让所有的action都可以使用get或者post方式访问 match "/:controller/:action" => "control ...
- 浅谈objective—C管理内存
这段时间被导师催着论文,调试各种BUg,也是醉了,发现很大程度上,内存出错,栈溢出,各种悲剧.那么今天就和大家一起对OC的内存管理来个探微吧.Objective-C使用一个保留计数记录了我们所创建的所 ...
- bat文件编写(无线承载网络设置)
就弄个例子,自己看执行效果,然后模仿写就行. 1)获取当前时间: @echo off set YEAR=%date:~0,4% set MONTH=%date:~5,2% set DAY=%date: ...
- PCRE正则库的使用
使用pcre编写C或C++程序,然后编译. 对于C程序,编译命令为:gcc -I/usr/local/include/pcre -L/usr/local/lib/pcre -lpcre file.c ...
- netlink
http://blog.csdn.net/zirconsdu/article/details/8569193 http://www.xuebuyuan.com/1725837.html netlink ...
- OSGi之Bundle
OSGi提出的根源是什么?在我看来就是对JVM的类加载机制进行了扩展,添加了一系列的规则,使得原有的类包(Class Package)扩展到类域(Class Domain).然后是建立在类域上的一系列 ...
- Win7下的本地网站发布
今天闲来无事研究了一下网站的发布,之前一直以为很难的样子,当真正实现了就觉得他也不过如此,现在来把我的研究结果分享一下,如果有问题望大家提出来! 首先发布网站我们要在本地的电脑上安装IIS,这个就不多 ...
- R 语言中文乱码问题
R 语言似乎在WINDOWS平台上对中文的支持不是特别好,似乎是3.1.2的一个BUG. 目前我研究出了一个临时解决方案,你可以将代码编写成一个函数,从而在调用的过程中不必如下繁琐: 1. 先将本地语 ...
- vim替换及多行注释命令
1.多行注释: . 进入命令行模式,按ctrl + v进入 visual block模式,然后按j, 或者k选中多行,把需要注释的行标记起来 . 按大写字母I,再插入注释符,例如// . 按esc键就 ...
- Window VNC远程控制LINUX:VNC详细配置介绍
Window VNC远程控制LINUX:VNC详细配置介绍 //---------------------------------------vnc linux下的详细配置 1.VNC的启动/停止/重 ...