hdu 1588 Gauss Fibonacci(矩阵嵌矩阵)
题目大意:
求出斐波那契中的 第 k*i+b 项的和。
思路分析:
定义斐波那契数列的矩阵
f(n)为斐波那契第n项
F(n) = f(n+1)
f(n)
那么能够知道矩阵
A = 1 1
1 0
使得 F(n) = A * F(n+1)
然后我们化简最后的答案
sum = F(b) + F(K+b) + F (2*k +b)....
sum = F(b) + A^k F(b) + A^2k F(b).....
sum = (E+A^k + A^2k.....)*F(b)
那么我们把 矩阵 A^k 定义为矩阵 K。
再递推上面的求和公式。
E E * SUM = SUM + E
0 K E K
所以构造一个内嵌矩阵的矩阵。
然后求出和乘以F(b)就可以。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <iostream>
#define N 2
using namespace std;
typedef long long LL;
LL mod;
struct matrix
{
LL data[N][N];
friend matrix operator * (const matrix A,const matrix B)
{
matrix res;
memset(res.data,0,sizeof res.data);
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++)
res.data[i][j]+=(A.data[i][k]*B.data[k][j])%mod;
return res;
}
friend matrix operator + (const matrix A,const matrix B)
{
matrix res;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
res.data[i][j]=(A.data[i][j]+B.data[i][j])%mod;
return res;
}
friend matrix operator - (const matrix A,const matrix B)
{
matrix res;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
res.data[i][j]=((A.data[i][j]-B.data[i][j])+mod)%mod;
return res;
}
void print()
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
printf("%I64d ",data[i][j]);
puts("");
}
} }E,zero;
struct supermax
{
matrix ret[N][N];
friend supermax operator * (supermax A,supermax B)
{
supermax res;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
res.ret[i][j]=zero; for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++)
{
res.ret[i][j]=res.ret[i][j]+(A.ret[i][k]*B.ret[k][j]);
for(int p=0;p<N;p++)
for(int q=0;q<N;q++)
res.ret[i][j].data[p][q]%=mod;
}
return res;
}
}; matrix matmod(matrix origin,LL n)
{
matrix res=E; while(n)
{
if(n&1)
res=res*origin;
n>>=1;
origin=origin*origin;
}
return res;
}
supermax Do(supermax origin,LL n)
{
supermax res;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
res.ret[i][j]=zero;
for(int i=0;i<N;i++)
res.ret[i][i]=E; while(n)
{
if(n&1)
res=res*origin;
n>>=1;
origin=origin*origin;
}
return res;
}
int main()
{
memset(zero.data,0,sizeof zero.data);
memset(E.data,0,sizeof E.data);
for(int i=0;i<N;i++)
E.data[i][i]=1; LL k,b,n;
while(scanf("%I64d%I64d%I64d%I64d",&k,&b,&n,&mod)!=EOF)
{
matrix fib;
fib.data[0][0]=1;
fib.data[0][1]=1;
fib.data[1][0]=1;
fib.data[1][1]=0; matrix K=matmod(fib,k); supermax o;
o.ret[0][0]=E;
o.ret[0][1]=E;
o.ret[1][0]=zero;
o.ret[1][1]=K; supermax final=Do(o,n); matrix tmp=(final.ret[0][0]*zero)+(final.ret[0][1]*E); matrix B=matmod(fib,b);
matrix fibb,fib0;
fib0.data[0][0]=1;
fib0.data[1][0]=0;
fib0.data[0][1]=fib0.data[1][1]=0;
fibb=B*fib0; matrix ans = tmp*fibb;
printf("%I64d\n",ans.data[1][0]%mod);
}
return 0;
}
hdu 1588 Gauss Fibonacci(矩阵嵌矩阵)的更多相关文章
- HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)
HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出 ...
- HDU - 1588 Gauss Fibonacci (矩阵高速幂+二分求等比数列和)
Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very cle ...
- HDU 1588 Gauss Fibonacci(矩阵快速幂)
Gauss Fibonacci Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU:Gauss Fibonacci(矩阵快速幂+二分)
http://acm.hdu.edu.cn/showproblem.php?pid=1588 Problem Description Without expecting, Angel replied ...
- hdu 1588(Fibonacci矩阵求和)
题目的大意就是求等差数列对应的Fibonacci数值的和,容易知道Fibonacci对应的矩阵为[1,1,1,0],因为题目中f[0]=0,f[1]=1,所以推出最后结果f[n]=(A^n-1).a, ...
- 【HDU 2855】 Fibonacci Check-up (矩阵乘法)
Fibonacci Check-up Problem Description Every ALPC has his own alpc-number just like alpc12, alpc55, ...
- POJ3233]Matrix Power Series && [HDU1588]Gauss Fibonacci
题目:Matrix Power Series 传送门:http://poj.org/problem?id=3233 分析: 方法一:引用Matrix67大佬的矩阵十题:这道题两次二分,相当经典.首先我 ...
- hdu 1588(矩阵好题+递归求解等比数列)
Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HDU 5411 CRB and puzzle (Dp + 矩阵高速幂)
CRB and Puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) T ...
随机推荐
- caioj 1087 动态规划入门(非常规DP11:潜水员)(二维背包)
这道题的难点在于价值可以多. 这道题我一开始用的是前面的状态推现在的状态 实现比较麻烦,因为价值可以多,所以就设最大价值 为题目给的最大价值乘以10 #include<cstdio> #i ...
- caioj 1078 动态规划入门(非常规DP2:不重叠线段)(状态定义问题)
我一开始想的是前i个区间的最大值 显然对于当前的区间,有不选和选两种情况 如果不选的话,就继承f[i-1] 如果选的话,找离当前区间最近的区间取最优 f[i] = max(f[i-1, f[j] + ...
- 2014 CodingTrip - 携程编程大赛 (预赛第一场)
1001: 可以证明(扩展欧几里得),只要卡片中有两个卡片互素,旁边点就是可达的. 因此只需要算出所有卡片不互素的情况有多少种,可用容斥原理. #include <cstdio> #inc ...
- 【Round #36 (Div. 2 only) C】Socks Pairs
[题目链接]:https://csacademy.com/contest/round-36/task/socks-pairs/ [题意] 给你n种颜色的袜子,每种颜色颜色的袜子有ai只; 假设你在取袜 ...
- Java基础学习总结(13)——流IO
一.JAVA流式输入/输出原理 流是用来读写数据的,java有一个类叫File,它封装的是文件的文件名,只是内存里面的一个对象,真正的文件是在硬盘上的一块空间,在这个文件里面存放着各种各样的数据,我们 ...
- 找出BST里面与Target最接近的n个数
http://www.cnblogs.com/jcliBlogger/p/4771342.html 这里给了两种解法,一种是利用C++的priority_queue,然后逐个node输入. 另一种是先 ...
- 进程:linux用户态-内核态
用户态:Ring3运行于用户态的代码则要受到处理器的诸多检查,它们只能访问映射其地址空间的页表项中规定的在用户态下可访问页面的虚拟地址,且只能对任务状态段(TSS)中I/O许可位图(I/O Permi ...
- LVDS原理及设计指南
LVDS是一种低摆幅的差分信号技术,它使得信号能在差分PCB 线对或平衡电缆上以 几百Mbps的速率传输,其低压幅和低电流驱动输出实现了低噪声和低功耗. IEEE 在两个标准中对LVDS ...
- 整个shuffle的流程图
整个shuffle的流程图 Paste_Image.png Map Shuffle的作用以及相应的设置 partition 过程:输入的<key,value>对经过map()处理后输出 ...
- DELL T110 II 系统安装总结
DELL T110 II 系统安装总结 1.RAID制作:https://jingyan.baidu.com/article/a3aad71ac4ce98b1fb0096bc.html 2.系统安装 ...