题目大意:自己看去
题解:这真是一道神题,由于有大量的数学公式,不太好写(我懒,就附个链接吧
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<algorithm>
#include<ctime>
#include<cmath>
using namespace std;
#define int long long
#define mod p
int ys[100000];
int top=0;
void fenjie(int n)
{
top=0;
int i;
for(i=2;i*i<n;i++)
if(n%i==0)
ys[++top]=i,ys[++top]=n/i;
if(i*i==n) ys[++top]=i;
}
long long n,k,p;
long long ksm(long long x,long long t)
{
long long re=1;
while(t)
{
if(t&1) re=re*x%mod;
x=x*x%mod;
t>>=1;
}
return re;
}
bool jud(int x)
{
for(int i=1;i<=top;i++)
if(ksm(x,ys[i])==1)
return false;
return true;
}
int get_w()
{
fenjie(p-1);
for(int i=2;;i++) if(jud(i)) return ksm(i,(p-1)/k);
}
struct zz
{
long long a[3][3];
zz operator + (zz b) const
{
zz mid;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
mid.a[i][j]=(a[i][j]+b.a[i][j])%p;
return mid;
}
zz operator * (long long b) const
{
zz mid;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
mid.a[i][j]=a[i][j]*b%p;
return mid;
}
zz operator * (zz b) const
{
zz mid;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
{
mid.a[i][j]=0;
for(int k=1;k<=2;k++)
{
mid.a[i][j]+=a[i][k]*b.a[k][j];
mid.a[i][j]%=p;
}
}
return mid;
}
}trans,ji;
long long ksm(zz x,long long t)
{
zz re=ji;
while(t)
{
if(t&1) re=re*x;
t>>=1;
x=x*x;
}
return (re.a[1][1]+re.a[2][1])%mod;
}
void init()
{
ji.a[1][1]=ji.a[2][2]=1;
trans.a[1][1]=0;
trans.a[1][2]=trans.a[2][1]=trans.a[2][2]=1;
}
int w;
void print(zz b)
{
for(int i=1;i<=2;i++,cout<<endl)
for(int j=1;j<=2;j++,cout<<" ")
cout<<b.a[i][j];
}
main()
{
int T;
scanf("%lld",&T);
init();
while(T--)
{
scanf("%lld%lld%lld",&n,&k,&p);
w=get_w();
long long trueans=0;
for(int j=0;j<k;j++)
{
long long x=ksm(ksm(w,j),p-2);
trueans+=ksm(ksm(x,n),p-2)*(ksm(trans+(ji*x),n));
trueans%=p;
}
trueans*=ksm(k,p-2);
trueans%=p;
printf("%lld\n",trueans);
}
return 0;
}