http://acm.hdu.edu.cn/showproblem.php?pid=5451
如果指数不是那么大的话,就和那个SO EAST那道题一样的用矩阵快速幂来做
但是指数是2的2的31次方那么大,底数还是个无理数, 降幂不能
看了别人的优秀代码 ,发现是寻找循环节.因为模数很小.
对于每一个模数,都有自己的循环节.
向上取整的递推公式是 Cn=10*Cn-1 -Cn-2
那么只要有一对连续的数重复出现,那么整个数列就都会循环起来了.所以能够找循环节.
机智啊!!!!!!!
注意写的过程中,如果感觉会发生负数取模的地方,不妨都加一个模数再来取模.
#include<bits/stdc++.h>
using namespace std;
long long x,mod;
long long C[55555];
long long find()
{
C[0]=2;
C[1]=10;
for(long long i=2;i<=48888;i++)
{
C[i]=C[i-1]*10-C[i-2];
C[i]=(C[i]+mod)%mod;
if(C[i]==C[1]&&C[i-1]==C[0])
{
return i;
}
}
}
long long qpow(long long a,long long cs,long long p)
{
long long ans=1;
while(cs)
{
if(cs&1)
ans=ans*a%p;
a=a*a%p;
cs>>=1;
}
return ans;
}
long long solve()
{
long long xhj=find();
xhj--;
long long zs=(1+qpow(2,x,xhj))%xhj;
return (C[zs]-1+mod)%mod;
}
int main()
{
int t;
int cs=1;
cin>>t;
while(t--)
{
scanf("%lld%lld",&x,&mod);
printf("Case #%d: %lld\n",cs++,solve());
}
return 0;
}