2 1 4 100 2 0 4 100
21 12
题解及代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int mod=1e9;
struct mat
{
__int64 t[4][4];
void set()
{
memset(t,0,sizeof(t));
}
} a,b,c;
mat multiple(mat a,mat b,int n,int p)
{
int i,j,k;
mat temp;
temp.set();
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
if(a.t[i][j]!=0)
for(k=0; k<n; k++)
temp.t[i][k]=(temp.t[i][k]+a.t[i][j]*b.t[j][k]+p)%p;
}
return temp;
}
mat quick_mod(mat b,int n,int m,int p)
{
mat t;
t.set();
for(int i=0;i<n;i++) t.t[i][i]=1;
while(m)
{
if(m&1)
{
t=multiple(t,b,n,p);
}
m>>=1;
b=multiple(b,b,n,p);
}
return t;
}
void init1()
{
b.set();
b.t[0][1]=1;
b.t[1][0]=1;
b.t[1][1]=1;
}
void init2()
{
b.t[0][2]=1;
b.t[1][3]=1;
b.t[2][2]=1;
b.t[3][3]=1;
}
int main()
{
int _k,_b,_n,M;
while(cin>>_k>>_b>>_n>>M)
{
init1();
a=quick_mod(b,2,_b,M);
init1();
b=quick_mod(b,2,_k,M);
init2();
c=quick_mod(b,4,_n,M);
__int64 ans=0;
b.t[0][0]=c.t[0][2];
b.t[0][1]=c.t[0][3];
b.t[1][0]=c.t[1][2];
b.t[1][1]=c.t[1][3];
c=multiple(a,b,2,M);
ans=c.t[1][0];
cout<<ans<<endl;
}
return 0;
}
/*
F为斐波那契数列:F[0]=0,F[1]=1,F[n]=F[n-1]+F[n-2];
g为一个函数,g(i)=k*i+b;
S[n]=∑F[g(i)]=F[b]+F[k+b]+F[k*2+b]+……+F[k*(n-1)+b]
我们设A为斐波那契数列的初始矩阵,B为转换矩阵
那么S[n]=A*B^b+A*B^(k+b)+A*B^(k*2+b)+……+A*B^((n-1)*k+b)
=A*B^b*(I+B^k+B^(2*k)+……+B^((n-1)*k))
那么我们这里只需要求出A,B^b和I+B^k+B^(2*k)+……+B^((n-1)*k)就可以了
当然前两个比较好求,关键是后面这个,首先我们可以先求出B^k=C
然后在构造一个4*4的矩阵来求和
|C I| 其二次方是|C^2 I+C| 三次方|C^3 I+C+C^2| …… 这样我们就能求出和了。
|0 I| |0 I| |0 I|
*/
hdu 1588 Gauss Fibonacci(矩阵快速幂),布布扣,bubuko.com
hdu 1588 Gauss Fibonacci(矩阵快速幂)
原文:http://blog.csdn.net/knight_kaka/article/details/38185163