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算法的思想去转移,借助这个题目也理解了 ...
随机推荐
- ###Android 断点调试和高级调试###
转自:http://www.2cto.com/kf/201506/408358.html 有人说Android 的调试是最坑的,那我只能说是你不会用而已,我可以说Android Studio的调试是我 ...
- 八款强大的jQuery图片滑块动画插件
jQuery是一款相当轻巧的JavaScript框架,目前几乎每一个WEB项目都在使用jQuery,因为jQuery插件实在太丰富,尤其是 一些图片滑块插件和jQuery焦点图插件,更是多如牛毛,很多 ...
- Combination Sum II 解答
Question Given a collection of candidate numbers (C) and a target number (T), find all unique combin ...
- Number of Containers(数学) 分类: 数学 2015-07-07 23:42 1人阅读 评论(0) 收藏
Number of Containers Time Limit: 1 Second Memory Limit: 32768 KB For two integers m and k, k is said ...
- MongoDBAuth
1,mogoDB 认证登陆
- Spring(二)——IoC
IoC(Inversion of Control)称之为控制反转,指的是在Spring框架的配置文件中声明对象,由框架负责创建对象,这叫做控制反转.实现方式有两种:DI(Dependency Inje ...
- 449A - Jzzhu and Chocolate 贪心
一道贪心题,尽量横着切或竖着切,实在不行在交叉切 #include<iostream> #include<stdio.h> using namespace std; int m ...
- Eclipse SVN插件的帐号、password改动
问题描写叙述: Eclipse的SVN插件Subclipse做得非常好,在svn操作方面提供了非常强大丰富的功能.但到眼下为止,该插件对svn用户的概念极为淡薄,不但不能方便地切换用户,并且一旦用户的 ...
- java学习之部分笔记2
1.变量 实例变量和局部变量 实例变量系统会自动初始化为0和null(string),局部变量必须设定初始值. 静态方法里只能引用静态变量 数据类型的自动转换! int—>long 2.构造方法 ...
- 基于.Net的单点登录(SSO)解决方案
前些天一位朋友要我帮忙做一单点登录,其实这个概念早已耳熟能详,但实际应用很少,难得最近轻闲,于是决定通过本文来详细描述一个SSO解决方案,希望对大家有所帮助.SSO的解决方案很多,但搜索结果令人大失所 ...