题解:由于pq互质所以要求f[n]mod phi(q)。然后f[n]用矩乘计算即可。然后快速幂即可。
及说此题卡常需要先预处理出一些质数。
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXV 5
#define MAXP 1000000
#define lint long long
#define debug(x) cerr<<x
#define sp <<" "
#define ln <<endl
using namespace std;
int mod;
struct matrix{
int v[MAXV][MAXV],n,m;
inline matrix set_size(int _n=0,int _m=0)
{
n=_n,m=_m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
v[i][j]=0;
return *this;
}
matrix(int _n=0,int _m=0)
{
set_size(_n,_m);
}
inline matrix operator=(const matrix &b)
{
n=b.n,m=b.m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
v[i][j]=b.v[i][j];
return *this;
}
inline matrix operator*(const matrix &b)
{
matrix &a=(*this),c(a.n,b.m);
if(a.m^b.n) return c;
for(int i=1;i<=a.n;i++)
for(int k=1;k<=b.m;k++)
for(int j=1;j<=a.m;j++)
c.v[i][k]=(c.v[i][k]+(lint)a.v[i][j]*b.v[j][k]%mod)%mod;
return c;
}
inline friend matrix operator*=(matrix &a,const matrix &b)
{
return a=a*b;
}
}A(2,2),B(2,1);
bool notp[MAXP];int pri[MAXP],pri_cnt;
inline int LinearShaker(int n)
{
notp[1]=true;pri_cnt=0;
for(int i=2;i<=n;i++)
{
if(!notp[i]) pri[++pri_cnt]=i;
for(int j=1;j<=pri_cnt;j++)
{
if((lint)pri[j]*i>n) break;
notp[pri[j]*i]=true;
if(i%pri[j]==0) break;
}
}
return pri_cnt;
}
inline int get_phi(int x)
{
if(x==1) return 1;
int ans=x;
for(int j=1;(lint)pri[j]*pri[j]<=x;j++)
if(x%pri[j]==0)
{
ans=(lint)ans*(pri[j]-1)/pri[j];
while(x%pri[j]==0) x/=pri[j];
}
return (x>1)?((lint)ans*(x-1)/x):ans;
}
inline int fast_pow(int x,int k,int mod)
{
if(k==0) return 1%mod;
if(k==1) return x%mod;
int ans=fast_pow(x,k>>1,mod);
ans=(lint)ans*ans%mod;
if(k&1) ans=(lint)ans*x%mod;
return ans;
}
inline matrix matrix_pow(const matrix &a,int k)
{
if(k==1) return a;
matrix ans=matrix_pow(a,k/2);
ans*=ans;if(k&1) ans*=a;
return ans;
}
inline int get_fn(int n,int m)
{
if(n==1) return 1%m;
mod=m;A.v[1][1]=A.v[1][2]=A.v[2][1]=1%m;A.v[2][2]=0;
B.v[1][1]=1%m;B.v[2][1]=0;
B=matrix_pow(A,n-1)*B;
return B.v[1][1];
}
int main()
{
LinearShaker(MAXP);
int m,p;scanf("%d%d",&m,&p);
while(m--)
{
int n,q;scanf("%d%d",&n,&q);
printf("%d\n",fast_pow(p%q,get_fn(n,get_phi(q)),q));
}
return 0;
}