HDU1588___矩阵快速幂and斐波拉契通项的矩阵算法
2013-04-15 15:26
357 查看
整个算法来自http://blog.sina.com.cn/s/blog_626631420100vsug.html
他本人写的非常的清楚,感谢。
题目中的公式:
f(0)=0 f(1)=1
f(n)=f(n-1)+f(n-2) (n>=2)
g(i)=k*i+b;
对于Fib序列:
如果用F表示上市中的矩阵就有 F(n+1) = AF(n) 是等比数列
g(i)=k*i+b 是等差数列
所以F(g(i)) = F(b) + F(b+k)+F(b+2k)+....+F(b+nk)
= F(b) + (A^k)F(b) + (A^2k)F(b)+….+(A^nk)F(b)
提取公因式 F(b)
= F(b) [ E +A^k + A^2k + ….+ A^nk] (式中E表示的是单位矩阵)
令 K = A^k 后
E +A^k + A^2k + ….+ A^nk 变成 K^0+K^1+K^2+…+K^n
构造矩阵
我的代码如下:
他本人写的非常的清楚,感谢。
题目中的公式:
f(0)=0 f(1)=1
f(n)=f(n-1)+f(n-2) (n>=2)
g(i)=k*i+b;
对于Fib序列:
如果用F表示上市中的矩阵就有 F(n+1) = AF(n) 是等比数列
g(i)=k*i+b 是等差数列
所以F(g(i)) = F(b) + F(b+k)+F(b+2k)+....+F(b+nk)
= F(b) + (A^k)F(b) + (A^2k)F(b)+….+(A^nk)F(b)
提取公因式 F(b)
= F(b) [ E +A^k + A^2k + ….+ A^nk] (式中E表示的是单位矩阵)
令 K = A^k 后
E +A^k + A^2k + ….+ A^nk 变成 K^0+K^1+K^2+…+K^n
构造矩阵
我的代码如下:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define LL long long struct matrix { LL data[2][2]; }E,A,O; struct supMatrix { matrix m[2][2]; }SUPE,SUPA; int k,b,n,M; void init() { E.data[0][0] = E.data[1][1] = 1; E.data[0][1] = E.data[1][0] = 0; A.data[0][0] = A.data[0][1] = A.data[1][0] = 1; A.data[1][1] = 0; O.data[0][0] = O.data[0][1] = O.data[1][0] = O.data[1][1] = 0; SUPE.m[0][0] = SUPE.m[1][1] = E; SUPE.m[0][1] = SUPE.m[1][0] = O; } matrix m_mul(matrix X,matrix Y) { matrix ans = O; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { for(int k=0;k<2;k++) { ans.data[i][j]+=X.data[i][k]*Y.data[k][j]; ans.data[i][j]%=M; } } } return ans; } matrix m_power(int x,matrix st) { matrix X = st; matrix Y = E; if(x==0) return Y; while(x!=1) { if(x&1) { x--; Y=m_mul(Y,X); } else { x=x>>1; X=m_mul(X,X); } } return m_mul(X,Y); } matrix m_add(matrix X,matrix Y) { matrix ret = O; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { ret.data[i][j] = X.data[i][j]+Y.data[i][j]; ret.data[i][j] %= M; } } return ret; } supMatrix sm_mul(supMatrix X,supMatrix Y) { supMatrix ret; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { ret.m[i][j] = O; for(int k=0;k<2;k++) { ret.m[i][j] = m_add(ret.m[i][j],m_mul(X.m[i][k],Y.m[k][j])); } } } return ret; } supMatrix sm_power(int x,supMatrix st) { supMatrix X = st; supMatrix Y = SUPE; if(x==0) return Y; while(x!=1) { if(x&1) { x--; Y=sm_mul(Y,X); } else { x=x>>1; X=sm_mul(X,X); } } return sm_mul(X,Y); } int main() { init(); while(~scanf("%d%d%d%d",&k,&b,&n,&M)) { matrix Fb = m_power(b,A); matrix K = m_power(k,A); SUPA.m[0][0] = K; SUPA.m[0][1] = SUPA.m[1][1] = E; SUPA.m[1][0] = O; supMatrix ans1 = sm_power(n,SUPA); matrix KN = ans1.m[0][1]; matrix ans2 = m_mul(Fb,KN); printf("%I64d\n",ans2.data[1][0]); } return 0; }
相关文章推荐
- Jzzhu and Sequences CodeForces - 450B (矩阵快速幂)
- HDU1588 Gauss Fibonacci (矩阵快速幂+等比数列二分求和)
- [Lonlife1031]Bob and Alice are eating food(递推,矩阵快速幂)
- 【矩阵快速幂 】Codeforces 450B - Jzzhu and Sequences (公式转化)
- Codeforces Round #420 (Div. 2) E. Okabe and El Psy Kongroo 矩阵快速幂优化dp
- 斐波拉契快速求法:矩阵快速幂
- Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations 矩阵快速幂优化dp
- codeforces 450-B Jzzhu and Sequences 矩阵快速幂
- hdu 5564 Clarke and digits (数位dp + 矩阵快速幂优化)
- [Codeforces 719 E. Sasha and Array] 矩阵快速幂+线段树
- hdu1588 Gauss Fibonacci(矩阵快速幂+二分求矩阵等比和)
- Codeforces 450B-Jzzhu and Sequences (矩阵快速幂)
- Codeforces Round #420 (Div. 2) Okabe and El Psy Kongroo[矩阵快速幂+细节处理]
- Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks(dp + 矩阵快速幂)
- cf#307-D. GukiZ and Binary Operations-矩阵快速幂
- CF round#420 div.2 E Okabe and El Psy Kongroo【矩阵快速幂】
- Jzzhu and Sequences - CF 450B 矩阵快速幂版
- Codeforces Round #420 (Div. 2) E. Okabe and El Psy Kongroo dp+矩阵快速幂
- hdu 4549 M斐波拉契 (矩阵快速幂 + 费马小定理)
- HDU 4602 Partition (矩阵快速幂或求通项)