hdu1588之经典矩阵乘法
Gauss Fibonacci
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1706 Accepted Submission(s): 741
How good an opportunity that Gardon can not give up! The "Problem GF" told by Angel is actually "Gauss Fibonacci".
As we know ,Gauss is the famous mathematician who worked out the sum from 1 to 100 very quickly, and Fibonacci is the crazy man who invented some numbers.
Arithmetic progression:
g(i)=k*i+b;
We assume k and b are both non-nagetive integers.
Fibonacci Numbers:
f(0)=0
f(1)=1
f(n)=f(n-1)+f(n-2) (n>=2)
The Gauss Fibonacci problem is described as follows:
Given k,b,n ,calculate the sum of every f(g(i)) for 0<=i<n
The answer may be very large, so you should divide this answer by M and just output the remainder instead.
Each of them will not exceed 1,000,000,000.
2 0 4 100
12
题目要求求出f(g(i))的总和,i是0~n-1
代码中详细思路+注释
/*f(g(i))=f(k*i+b)
令f[n]=A;//A是矩阵,A的某个元素是F[n]
若i=0~n-1,则sum(f(k*i+b))
=A^b+A^(k+b)+A^(2k+b)+A^(3k+b)+...+A^((n-1)k+b)
=A^b+A^b(A^k+A^2k+A^3k+A^4k+...+A^(n-1)k)
将A^k看成一个新的矩阵B,则原式:
=A^b+A^b(B^1+B^2+B^3+...+B^(n-1));//A^b,A^k用矩阵快速幂求出,括号中的用二分矩阵可求
所谓二分矩阵:A^1+A^2+A^3+A^4+A^5+A^6=(A^1+A^2+A^3)+A^3(A^1+A^2+A^3)
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std; const int MAX=2;
__int64 array[MAX][MAX],sum[MAX][MAX],temp[MAX][MAX],ans[MAX][MAX];
//array相当于A,sum记录每次幂乘后的矩阵,temp是临时矩阵,ans是B^1+B^2+B^3+...+B^n void MatrixInit(__int64 a[MAX][MAX],bool flag){//初始化矩阵
for(int i=0;i<MAX;++i){
for(int j=0;j<MAX;++j){
if(flag)a[i][j]=array[i][j];//a=A
else a[i][j]=(i == j);//a=1
}
}
} void MatrixAdd(__int64 a[MAX][MAX],__int64 b[MAX][MAX],int &mod){//矩阵相加
for(int i=0;i<MAX;++i){//a=a+b
for(int j=0;j<MAX;++j){
a[i][j]=(a[i][j]+b[i][j])%mod;
}
}
} void MatrixMult(__int64 a[MAX][MAX],__int64 b[MAX][MAX],int &mod){//矩阵相乘
__int64 c[MAX][MAX]={0};
for(int i=0;i<MAX;++i){//a=a*b
for(int j=0;j<MAX;++j){
for(int k=0;k<MAX;++k){
c[i][j]+=a[i][k]*b[k][j];
}
}
}
for(int i=0;i<MAX;++i){
for(int j=0;j<MAX;++j)a[i][j]=c[i][j]%mod;
}
} void MatrixPow(int k,int &mod){//矩阵幂乘,sum=A^k
MatrixInit(sum,0);//sum=1
MatrixInit(temp,1);//temp=A
while(k){
if(k&1)MatrixMult(sum,temp,mod);
MatrixMult(temp,temp,mod);
k>>=1;
}
} void MatrixSum(int k,int &mod){//矩阵求和
if(k == 1){MatrixInit(ans,1);return;}
MatrixSum(k/2,mod);
MatrixPow((k+1)/2,mod);
if(k&1){//k为奇数则A+(A+A^m)*(A+A^2+A^3...),m=(k+1)/2
MatrixInit(temp,1);//temp=A
MatrixAdd(sum,temp,mod);//sum=A+A^m
MatrixMult(ans,sum,mod);//ans=sum*ans
MatrixAdd(ans,temp,mod);//ans=A+ans
}
else{//k为偶数则(1+A^m)*(A+A^2+A^3...),m=(k+1)/2
MatrixInit(temp,0);//temp=1
MatrixAdd(temp,sum,mod);//temp=1+A^m
MatrixMult(ans,temp,mod);//ans=ans*temp;
}
} int main(){
int k,b,n,m;
while(scanf("%d%d%d%d",&k,&b,&n,&m)!=EOF){
array[0][0]=array[0][1]=array[1][0]=1;
array[1][1]=0;
MatrixPow(k,m);//求A^k
MatrixInit(array,0);
MatrixMult(array,sum,m);//将array构造成B,即A^k
MatrixSum(n-1,m);//求矩阵和
array[0][0]=array[0][1]=array[1][0]=1;
array[1][1]=0;
MatrixPow(b,m);//求A^b;
MatrixMult(ans,sum,m);//求A^b*ans
MatrixAdd(ans,sum,m);//求A^b+A^b+ans
printf("%I64d\n",ans[1][0]);
}
return 0;
}
hdu1588之经典矩阵乘法的更多相关文章
- poj3233之经典矩阵乘法
Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 12346 Accepted: ...
- zoj3497(经典矩阵乘法)
原以为是用搜索做的题,想了好久都无法想到一个高效正确的解法. 后面发现竟然这就是矩阵的应用! 碉堡! 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值 ——选自ma ...
- 学习心得:《十个利用矩阵乘法解决的经典题目》from Matrix67
本文来自:http://www.matrix67.com/blog/archives/tag/poj大牛的博文学习学习 节选如下部分:矩阵乘法的两个重要性质:一,矩阵乘法不满足交换律:二,矩阵乘法满足 ...
- 【转】Matrix67:十个利用矩阵乘法解决的经典题目
好像目前还没有这方面题目的总结.这几天连续看到四个问这类题目的人,今天在这里简单写一下.这里我们不介绍其它有关矩阵的知识,只介绍矩阵乘法和相关性质. 不要以为数学中的矩阵也是黑色屏幕上不断变化的 ...
- 【矩阵乘法经典应用】【ZOJ3497】【Mistwa】
题意:给定一个有向图(最多25个节点,每个节点的出度最多为4),给定起点和终点,然后从起点开始走,走到终点就停止,否则一直往下走,问能不能P步到达终点.也就是说从起点出发,走一条长度为P的路径,路径中 ...
- CH Round #30 摆花[矩阵乘法]
摆花 CH Round #30 - 清明欢乐赛 背景及描述 艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花.有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看 ...
- 【BZOJ-1898】Swamp 沼泽鳄鱼 矩阵乘法
1898: [Zjoi2005]Swamp 沼泽鳄鱼 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1012 Solved: 566[Submit][S ...
- 【poj3070】矩阵乘法求斐波那契数列
[题目描述] 我们知道斐波那契数列0 1 1 2 3 5 8 13…… 数列中的第i位为第i-1位和第i-2位的和(规定第0位为0,第一位为1). 求斐波那契数列中的第n位mod 10000的值. [ ...
- 如何使用矩阵乘法加速动态规划——以[SDOI2009]HH去散步为例
对这个题目的最初理解 开始看到这个题,觉得很水,直接写了一个最简单地动态规划,就是定义 f[i][j]为到了i节点路径长度为j的路径总数, 转移的话使用Floyd算法的思想去转移,借助这个题目也理解了 ...
随机推荐
- 在非MFC的win 32程序里面能够使用CString类
论坛有会员用到了.,今天给大家说说CSring如何在非mfc下的调用第一:先要包含 #include "afx.h" 包含之后会报windows.h重复定义我们需要把这个头文件包含 ...
- jprofiler安装和配置
转:http://www.cnblogs.com/adolfmc/archive/2013/06/09/3129358.html 注意:安装前先用rpm -q jprofiler查询linux上是否已 ...
- Word Break I II
Word Break Given a string s and a dictionary of words dict, determine if s can be segmented into a s ...
- UESTC_酱神寻宝 2015 UESTC Training for Dynamic Programming<Problem O>
O - 酱神寻宝 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- One Way Roads(搜索)
One Way Roads Time Limit:500MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Submit S ...
- Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8303098 在前文中,我们分析了应用程序窗口连 ...
- Android应用程序请求SurfaceFlinger服务创建Surface的过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7884628 前面我们已经学习过Android应 ...
- FFMPEG中最关键的结构体之间的关系
FFMPEG中结构体很多.最关键的结构体可以分成以下几类: a) 解协议(http,rtsp,rtmp,mms) AVIOContext,URLProtocol,URLContext主要 ...
- 在Android Studio中进行单元测试和UI测试
本篇教程翻译自Google I/O 2015中关于测试的codelab,掌握科学上网的同学请点击这里阅读:Unit and UI Testing in Android Studio.能力有限,如有翻译 ...
- 统计字符 比如aaabbcca----3a2b1c1a
package Demo; import java.util.Scanner; /** * Created by chengpeng on 16/11/3. */ /* idea command+al ...