推出公式:
1. F(n)= G(n)*G(n+1)/2:;
2. F ( n)= 5* F(n-1) + 5* F(n-2)-F(n-3)
公式:
(x^n)%c=x^(n%phi(c)+phi(c))%c;
原则:
方阵有结合律---没有交换律
思路:
先求出phi(s+1)--然后用矩阵求出F(n)%phi+phi---
然后快速幂求答案---
构造矩阵
A:
5 5 -1
1 0 0
0 1 0
和列向量
B
F [ 2 ]
F [ 1 ]
F [ 0 ]
C =A*B=
F [ 3 ]
F [ 2 ]
F [ 1 ]
F [ n ] F ( n-1 ) F [ 2 ]
F [ n-1] = A * F ( n-2 ) =A...........=A^(n-2)* F [ 1 ]
F [n-2] F (n-3) F [ 0 ]
代码1:
注意:
F(n)= G(n)*G(n+1)/2:
因为最后要除2---所以取模时我们要对2*phi取模-----
#include
#include
#include
using namespace std;
#define LLL long long
LLL mod;
struct node{
LLL shu[2][2];
void clear()
{
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
shu[i][j]=0;
}
node operator * (const node &B) const
{
node C;
C.clear();
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
for (int k=0;k<2;k++)
C.shu[i][j]=(C.shu[i][j]+shu[i][k]*B.shu[k][j])%mod;
return C;
}
}A,B,C,D;
LLL P[2]={0,1};
LLL phi(LLL xx)
{
LLL lp=xx;
for (LLL i=2;i*i<=xx;i++)
{
if (xx%i==0)
{
lp=lp-lp/i;
while (xx%i==0)
xx/=i;
}
}
if (xx>1)
lp=lp-lp/xx;
return lp;
}
LLL g(LLL xx)
{
LLL lp;
mod*=2;//注意
A.clear();
for (int i=0;i<2;i++)
A.shu[i][i]=1;
B.clear();
B.shu[1][0]=B.shu[0][1]=1;
B.shu[0][0]=2;
if (xx<3)
return P[xx];
while (xx)
{
if (xx&1)
A=A*B;
B=B*B;
xx>>=1;
}
lp=0;
lp=(A.shu[0][0]*A.shu[0][1])/2;
mod/=2;//注意
lp+=mod;
return lp;
}
void slove(LLL x,LLL n,LLL s)
{
mod=phi(s);
LLL lp=g(n);
LLL ans=1;
while (lp)
{
if (lp&1)
ans=(ans*x)%s;
x=(x*x)%s;
lp>>=1;
}
printf("%lld\n",ans);
}
int main()
{
int t;scanf("%d",&t);
while (t--)
{
LLL n,y,x,s;
scanf("%lld%lld%lld%lld",&n,&y,&x,&s);
n*=y;
s+=1;
slove(x,n,s);
}
return 0;
}
代码:
#include
#include
#include
using namespace std;
#define LLL long long
LLL mod;
struct node{
LLL shu[3][3];
void clear()
{
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
shu[i][j]=0;
}
node operator * (const node &B) const
{
node C;
C.clear();
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
for (int k=0;k<3;k++)
C.shu[i][j]=(C.shu[i][j]+shu[i][k]*B.shu[k][j])%mod;
return C;
}
}A,B,C,D;
LLL P[3]={0,1,5};
LLL phi(LLL xx)
{
LLL lp=xx;
for (LLL i=2;i*i<=xx;i++)
{
if (xx%i==0)
{
lp=lp-lp/i;
while (xx%i==0)
xx/=i;
}
}
if (xx>1)
lp=lp-lp/xx;
return lp;
}
LLL g(LLL xx)
{
LLL lp;
A.clear();
for (int i=0;i<3;i++)
A.shu[i][i]=1;
B.clear();
B.shu[0][0]=B.shu[0][1]=5;B.shu[0][2]=-1;
B.shu[1][0]=B.shu[2][1]=1;
if (xx<3)
return P[xx];
xx-=2;
while (xx)
{
if (xx&1)
A=A*B;
B=B*B;
xx>>=1;
}
lp=0;
for (int i=0;i<3;i++)
lp=(lp+A.shu[0][i]*P[2-i])%mod;
lp+=mod;
return lp;
}
void slove(LLL x,LLL n,LLL s)
{
mod=phi(s);
LLL lp=g(n);
LLL ans=1;
//printf("%lld %lld %lld %lld\n",x,lp,s,mod);
while (lp)
{
if (lp&1)
ans=(ans*x)%s;
x=(x*x)%s;
lp>>=1;
}
printf("%lld\n",ans);
}
int main()
{
int t;scanf("%d",&t);
while (t--)
{
LLL n,y,x,s;
scanf("%lld%lld%lld%lld",&n,&y,&x,&s);
n*=y;
s+=1;
// printf("%lld %lld %lld\n",x,n,s);
slove(x,n,s);
}
return 0;
}