思路:因为(5-sqrt(24))和(5+sqrt(24))是共轭复数,所以(5-sqrt(24))^n+(5+sqrt(24))^n一定是整数,然后因为(5-sqrt(24))<1,所以这个求出来的就是(5+sqrt(24))^n的向上取整的值,向下取整只需这个求出来减一即可,我们用cn表示(5-sqrt(24))^n+(5+sqrt(24))^n,cn*((5-sqrt(24))+(5+sqrt(24))),可以得到10*cn-cn-1=cn+1;这样递推式就得到了,因为幂过大但是模数很小,我们来找循环节,然后快速幂对循环节取模。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=47000;
#define ll long long
ll x,m;
ll ca[N];
ll f;
ll qpow(ll a,ll b)
{
ll ans=1;
a%=f;
while(b)
{
if(b&1)ans=ans*a%f;
a=a*a%f;
b>>=1;
}
return ans%f;
}
int main()
{
int T;
scanf("%d",&T);
int t=0;
while(T--)
{
scanf("%lld%lld",&x,&m);
ca[0]=2;
ca[1]=10;
f=m;
for(long long int i=2;i<N;i++)
{
ca[i]=(ca[i-1]*10-ca[i-2]+m)%m;
if(ca[i]==ca[1]&&ca[i-1]==ca[0])
{
f=i-1;
break;
}
}
x=qpow(2,x);
x=(x+1)%f;
printf("Case #%d: %lld\n",++t,(ca[x]-1+m)%m);
}
return 0;
}