教训:
因为:
1.矩阵中会牵扯到负数
2.牵扯到取模
所以:最后的结果可能为负!要记得调整成正的!!!
Fn=(a+sqrt(b))^n+(sqrt(b)-a)^n 是整数!就等于Sn。
F(0) = 2, F(1) = 2*a. 特征根就是 lamda = a+(-)sqrt(b)
递推方程是F(n+2) + (-2a) F(n+1) + (a^2-b)F(n) = 0 (真心没想到这步。。)
矩阵:
Fn+2 2a b-a^2 * Fn+1
Fn+1 = 1 0 Fn
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
long long int a,b,n,m;
struct matrix
{
long long int tz[2][2];
}origin;
void prt(matrix const &a)
{
for(int i=0;i<2;++i)
{
for(int j=0;j<2;++j)
cout<<a.tz[i][j]<<' ';
cout<<endl;
}
}
matrix multi(const matrix &a,const matrix &b)
{
matrix tmp;
memset (tmp.tz,0,sizeof(tmp.tz));
for (int i=0;i<2;++i)
for (int j=0;j<2;++j)
{
for (int l=0;l<2;++l)
tmp.tz[i][j]+=a.tz[i][l]*b.tz[l][j];
tmp.tz[i][j]%=m;
}
return tmp;
}
void cal (long long int n)
{
matrix now;
memset (now.tz,0,sizeof(now.tz));
now.tz[0][0]=now.tz[1][1]=1%m;
while (n)
{
if (n&1)
now=multi(now,origin);
n>>=1;
origin=multi(origin,origin);
}
// prt(now);
long long int ans=(now.tz[0][0]*2*a+now.tz[0][1]*2)%m;
cout<<(ans>=0?ans:ans+m)<<endl;
}
int main ()
{
while(cin>>a>>b>>n>>m)
{
origin.tz[0][0]=(2*a)%m;
origin.tz[0][1]=(b-a*a)%m;
origin.tz[1][0]=1%m;
origin.tz[1][1]=0;
// prt(origin);
if (n==0) cout<<2%m<<endl;
else if (n==1) cout<<(2*a)%m<<endl;
else cal(n-1);
}
return 0;
}