題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3221
AC代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=10000;
ll n,p,aa,b;
const ll maxn=1e6+10;
ll phi[maxn];
struct mat
{
ll a[2][2];
};
mat mat_mul(mat x,mat y)
{
mat res;
memset(res.a,0,sizeof(res.a));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++){
res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j]);
if(res.a[i][j]>phi[p])
res.a[i][j]=res.a[i][j]%phi[p]+phi[p];//在這裏歐拉降冪
}
return res;
}
mat mat_pow(ll n)
{
mat c,res;
c.a[0][0]=c.a[0][1]=c.a[1][0]=1;
c.a[1][1]=0;
memset(res.a,0,sizeof(res.a));
for(int i=0;i<2;i++)
res.a[i][i]=1;
while(n)
{
if(n&1)
res=mat_mul(res,c);
c=mat_mul(c,c);
n=n>>1;
}
return res;
}
void eulr()
{
for(int i=0;i<maxn;i++){
phi[i]=i;
}
for(int i=2;i<maxn;i++){
if(phi[i]==i){
for(int j=i;j<maxn;j+=i){
phi[j]=phi[j]/i*(i-1);
}
}
}
}
ll qpow(ll x,ll y,ll mo)
{
ll ans=1;
while(y){
if(y&1)
ans=ans*x%mo;
x=x*x%mo;
y>>=1;
}
return ans;
}
int main()
{
int t;
eulr();//預處理,不然會超時
//cout<<mat_pow(2)<<endl;
scanf("%d",&t);
int Case=0;
while(t--){
scanf("%lld%lld%lld%lld",&aa,&b,&p,&n);
// cout<<"Case #"<<++Case<<": ";
ll ta,tb;
ll ans;
if(n==1){//特判一下n==1,2情況
ans=aa%p;
}
else if(n==2){
ans=b%p;
}
else{
mat tmp=mat_pow(n-2);
ta=tmp.a[0][1];//斐波那契數列
tb=tmp.a[0][0];
ans=qpow(aa,ta,p)*qpow(b,tb,p)%p;
}
printf("Case #%d: %lld\n",++Case,ans);
}
return 0;
}