代码如下:
#include
#define ll long long
using namespace std;
const int maxn = 1000000 + 10;
ll MOD = 1e9 + 7;
ll a,b,n;
ll phi[maxn];
struct Matrix{
ll n, m;
ll mat[3][3];
Matrix(ll a = 0, ll b = 0):n(a),m(b) {memset(mat,0,sizeof(mat));}
void init(ll a, ll b) {n = a;m = b;}
Matrix operator *(const Matrix & x){
Matrix ans;ans.init(n,x.m);
for(int i = 1;i <= n;i++){
for(int j = 1;j <= x.m;j++){
for(int k = 1;k <= m;k++){
ans.mat[i][j] += mat[i][k] * x.mat[k][j];
if(ans.mat[i][j] > phi[MOD]) ans.mat[i][j] = ans.mat[i][j] % phi[MOD] + phi[MOD];
}
}
}
return ans;
}
};
Matrix q_pow(Matrix x, ll k){
Matrix ret;ret.init(2,2);
ret.mat[1][1] = ret.mat[2][2] = 1;
while(k > 0){
if(k & 1) ret = ret * x;
x = x * x;
k >>= 1;
}
return ret;
}
ll q_pow(ll x, ll k){
ll ret = 1;
while(k > 0){
if(k & 1) ret = ret * x % MOD;
x = x * x % MOD;
k >>= 1;
}
return ret;
}
int primes[maxn],pcnt;
void get_phi(int n){
memset(phi,0,sizeof(phi));
phi[1] = 1;int t = 0;
for(int i = 2;i <= n;i++){
if(!phi[i]) {
primes[++pcnt] = i;
phi[i] = i - 1;
}
for(int j = 1;j <= pcnt;j++){
t = primes[j];
if(i * t > n) break;
if(i % t == 0){
phi[i * t] = phi[i] * t;
break;
}
else phi[i * t] = phi[i] * (t - 1);
}
}
}
int main()
{
get_phi(maxn - 10);
int kase;scanf("%d",&kase);
int T = 0;
while(kase--){
printf("Case #%d: ",++T);
scanf("%I64d%I64d%I64d%I64d",&a,&b,&MOD,&n);
if(MOD == 1) {printf("0\n");continue;}
if(n == 1) {printf("%I64d\n",a % MOD);continue;}
if(n == 2) {printf("%I64d\n",b % MOD);continue;}
Matrix tmp;tmp.init(2,2);
tmp.mat[1][1] = 0;tmp.mat[1][2] = 1;
tmp.mat[2][1] = 1;tmp.mat[2][2] = 1;
Matrix p = Matrix(1,2);
p.mat[1][1] = 1;p.mat[1][2] = 1;
tmp = q_pow(tmp, n - 3);
p = p * tmp; ll ans = 1;
ans *= q_pow(a,p.mat[1][1]);
ans *= q_pow(b,p.mat[1][2]);
ans %= MOD;
printf("%I64d\n",ans);
}
return 0;
}