Question:
Find the sum of K * I + B in Fibonacci.
Train of Thought Analysis:
Defines the matrix of the Fibonacci series
F (n) is the nth entry of Fibonacci
F (n) = f (n + 1)
F (N)
Then we can know the matrix.
A = 1 1
1 0
Make F (n) = A * F (n + 1)
Then we simplify the final answer.
Sum = F (B) + f (K + B) + F (2 * k + B )....
Sum = F (B) + A ^ k f (B) + A ^ 2 k f (B ).....
Sum = (E + A ^ K + A ^ 2 k...) * F (B)
Then we define matrix A ^ K as matrix K.
Then, calculate the sum formula above.
E * sum = sum + E
0 k e k
Therefore, construct a matrix of embedded matrices.
Then obtain and multiply by F (B.
#include <cstdio>#include <iostream>#include <cstring>#include <iostream>#define N 2using 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;}