UVa 11582 - Colossal Fibonacci Numbers!(数论)

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2629

 

题意:

输入两个非负整数a、b和正整数n(0≤a,b<2^64,1≤n≤1000),你的任务是计算f(a^b)除以n的余数。
其中f(0)=0,f(1)=1,且对于所有非负整数i,f(i+2)=f(i+1)+f(i)。

 

分析:

所有计算都是对n取模的,设F(i)=f(i)%n。不难发现,当二元组(F(i), F(i+1))出现重复时,整个序列就开始重复。
多久会出现重复呢?因为余数最多n种,所以最多n*n项就会出现重复。实际测试出最多3001项左右就会出现重复。
所以只需计算出周期,然后算出F(a^b)对应于其中的哪一项即可。

 

代码:

 1 #include <cstdio>
 2 
 3 typedef unsigned long long ULL;
 4 const int UP = 1000 + 5;
 5 int f[UP][UP*3], period[UP];
 6 
 7 int qmod(ULL a, ULL b, ULL n) { // 快速幂模
 8     a %= n;
 9     ULL res = 1;
10     while(b) {
11         if(b & 1) res = res * a % n;
12         b >>= 1;
13         a = a * a % n;
14     }
15     return res;
16 }
17 
18 int main() {
19     period[1] = 1;
20     for(int n = 2; n <= 1000; n++) {
21         f[n][0] = 0;  f[n][1] = 1;
22         for(int i = 2; ; i++) {
23             f[n][i] = (f[n][i-1] + f[n][i-2]) % n;
24             if(f[n][i-1] == 0 && f[n][i] == 1) {
25                 period[n] = i - 1;
26                 break;
27             }
28         }
29     }
30 
31     int T, n;
32     ULL a, b;
33     scanf("%d", &T);
34     while(T--) {
35         scanf("%llu%llu%d", &a, &b, &n);
36         int p = qmod(a, b, period[n]);
37         printf("%d\n", f[n][p]);
38     }
39     return 0;
40 }

 

posted @ 2018-04-13 13:44  Ctfes  阅读(132)  评论(0编辑  收藏  举报