题意:求ceil((a+√b)n)%m,0< a, m < 215, (a-1)2< b < a2, 0 < b, n < 231。
思路:若(a+√b)n == x + y·√b(x、y为整数),则(a-√b)n == x - y·√b。又因为a-1 < √b < a,所以0 < (a-√b)n < 1,即x-1 < y·√b < x,所以ceil((a+√b)n) == 2x。接下来事情就容易多了,同时对x、y两部分进行快速幂取模即可,证明略。
1 #include2 typedef long long llg; 3 llg a,b,n,m; 4 void solve(){ 5 llg ans1(1),ans2(0),t1(a),t2(1); 6 llg tmp; 7 while(n){ 8 if(n&1){ 9 tmp = ans1;10 ans1 = (ans1*t1+ans2*t2*b)%m;11 ans2 = (tmp*t2+ans2*t1)%m;12 }13 tmp = t1;14 t1 = (t1*t1+t2*t2*b)%m;15 t2 = 2*tmp*t2%m;16 n >>= 1;17 }18 printf("%lld\n",ans1*2%m);19 }20 int main(){21 while(~scanf("%lld%lld%lld%lld",&a,&b,&n,&m))22 solve();23 return 0;24 }