// hdu 5667 矩阵快速幂
// 题意给个式子,然后取个对数,以a为底,第i项设为f(i)
// f(i} = b + c * f[i-1) + f(i - 2)
// 我构造的矩阵为
// | 1 0 0 | | b | | b |
// | 0 0 1 | * | f(n-1) | = | f(n) |
// | 1 1 c | | f(n) | | f(n+1) |
// 模的数有个公式.因为p是质数,所以phi(p) = p - 1
// 一直没有check a % p == 0 所以一直wa
#include <cstdio>
#include <math.h>
#include <cstring>
typedef long long ll;
ll mod;
struct Matrix{
ll a[4][4];
}M;
Matrix Mulity(Matrix a,Matrix b){
Matrix c;
memset(c.a,0,sizeof(c.a));
for (int i = 1;i <= 3;i ++){
for (int j = 1;j <= 3;j ++){
for (int k = 1;k <= 3;k ++){
c.a[i][j] = (c.a[i][j] + (a.a[i][k] * b.a[k][j]) % mod) % mod;
}
}
}
return c;
}
Matrix Pow(Matrix a,ll b){
Matrix res;
memset(res.a,0,sizeof(res.a));
res.a[1][1] = res.a[2][2] = res.a[3][3] = 1;
while(b){
if (b & 1)
res = Mulity(res,a);
a = Mulity(a,a);
b >>= 1;
}
return res;
}
ll Powll(ll a,ll b){
ll res = 1;
while(b){
if (b & 1)
res = res * a % (mod + 1);
a = a * a % (mod + 1);
b >>= 1;
}
return res % (mod + 1);
}
int main(){
int t;
//freopen("1.txt","r",stdin);
scanf("%d",&t);
while(t--){
int a,b,c,p;
ll n;
scanf("%I64d%d%d%d%d",&n,&a,&b,&c,&p);
mod = p - 1;
if (n == 1){
printf("1\n");
continue;
}
if (n == 2){
printf("%I64d\n",Powll(a,b));
continue;
}
if (a % p == 0){
puts("0");
continue;
}
memset(M.a,0,sizeof(M.a));
M.a[1][1] = 1;
M.a[2][3] = 1;
M.a[3][1] = 1;
M.a[3][2] = 1;
M.a[3][3] = c;
M = Pow(M,n-1);
ll res = (M.a[2][1] % mod * b % mod + M.a[2][3] % mod * b % mod) % mod;
printf("%I64d\n",Powll(a,res));
}
return 0;
}
hdu 5667 矩阵快速幂
最新推荐文章于 2018-10-09 23:54:43 发布