题意 : 给出 n ,x,y,s,f[0] = 0 f[1]=1, f[n] = 2*f[n-1]+f[n-2] ,g[n] = g[n-1] +f[n]*f[n]
求 x^g(n*y)%s;
首先先求出 g[n] = f[n]*f[n-1]/2; 这个类似于高中求数列和。。 将 f[n] 划到一边,求和
然后就是 一个公式: a^b%c = a^(b%phi(c)+phi(c))%c phi(c) 为 c 的欧拉函数值
然而mod的数带除数 又有一个公式: a/b%c = a%(b*c)/b b,c互素不互素都有这个
顺便提一下 a/b%c = a*b^(phi(c) - 1)%c bc不互素
然后就是矩阵快速幂和快速幂了
#include<bits/stdc++.h>
using namespace std;
struct Matrix
{
long long mat[2][2];
};
Matrix unit_matrix =
{
1,0,
0,1
};
Matrix mul(Matrix a ,Matrix b,long long mod)
{
Matrix res;
for(int i = 0; i<2; i++)
for(int j = 0; j<2; j++)
{
res.mat[i][j] = 0;
for(int k = 0; k<2; k++)
{
res.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
res.mat[i][j]%= mod;
}
}
return res;
}
Matrix pow_matrix(Matrix a ,long long n,long long mod)
{
Matrix res = unit_matrix;
while(n!=0)
{
if(n&1)
res = mul(res,a,mod);
a = mul(a,a,mod);
n>>=1;
}
return res;
}
long long phi(long long n)
{
long long m = (long long )sqrt(n+0.5);
long long ans = n;
for(long long i = 2; i<=m; i++)
{
if(n%i==0)
{
ans = ans/i*(i-1);
while(n%i==0)
{
n/=i;
}
}
}
if(n>1)
ans = ans/n*(n-1);
return ans;
}
long long pow_mod(long long x,long long y,long long mod)
{
long long res = 1;
while(y)
{
if(y&1)
res =res*x%mod;
x = x*x%mod;
y/=2;
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
long long n ,y ,x,s;
scanf("%lld%lld%lld%lld",&n,&y,&x,&s);
s+=1;
long long mod = phi(s);
mod*=2;
Matrix a ;
a.mat[0][0] = 2;
a.mat[0][1] = 1;
a.mat[1][0] = 1;
a.mat[1][1] = 0;
Matrix ans = pow_matrix(a,n*y,mod);
long long g=(ans.mat[0][0]*ans.mat[0][1]%mod/2+mod/2);
printf("%lld\n",pow_mod(x,g,s));
}
return 0;
}