UVA 11582 - Colossal Fibonacci Numbers!【大数幂取模】

来源:互联网 发布:气动打标机软件下载 编辑:程序博客网 时间:2024/05/20 20:01
Colossal Fibonacci Numbers!
Time Limit: 1000MS  Memory Limit: Unknown
Description:
The i’th Fibonacci numberf(i) is 
recursively defined in the following 
way:
f (0)  =  0  and   f (1)  = 1
f ( i + 2 )  =  f(i + 1)  +  f( i )
for 
everyi  ≥  0 .
Your task is to compute some 
values of this sequence.

Input:
Input begins with an integert  ≤ 10, 000, the number of test cases.Each test case consists of three integersa,b,n where 0 ≤  a, b < 2^64(a and  b will not both be zero) and 1 ≤   ≤ 1000.

Output:
For each test case, output a single line containing the remainder of  f(a^b) upon division byn.

Sample Input:
3
1   1   2
2   3   1000
18446744073709551615   18446744073709551615   1000

Sample Output:
1
21
250



算法分析:
所有的计算都是对n取模,设F (i) =f (i) modn,很容易发现,当二元组(F (i - 1),(i )) 重复的时候,整个序列也就重复。
例,n = 3,序列 F( i ) 的前 10 项为1,1,2,0,2,2,1,0,1,1,第 9、10 项和前两项完全一样。根据递推公式,第11项会等于第3项,第12项等于第4项……,从而找出规律以及循环节长度!

代码实现:
#include <stdio.h>#include <iostream>#include <string.h>#include <algorithm>using namespace std;typedef unsigned long long ull;const int Max = 10010;int f[Max];ull a, b;int solve(int n)///找出余数为n时的循环节长度{    f[0] = 0;    f[1] = 1 % n;///开始没对f[1]做模运算,无数次Runtime Error    for(int i = 2; i ; i++)    {        f[i] = (f[i - 1] % n + f[i -2] % n) % n;        if(f[i] == f[0] && (f[i] + f[i-1]) % n == f[1])            return i;    }    return 1;}int pow(int a, ull b, int m)///幂取模运算(a^b)%m(采用分治法降低时间复杂度){    int mid, ans;    if(b == 0)        return 1%m;    mid = pow(a,b/2,m);    ans = mid * mid % m;    if(b&1)        ans = ans * a % m;    return ans;}int main(){    int t;    scanf("%d",&t);    while (t--)    {        int n, mod, ans;        cin >> a >> b >> n;        mod = solve(n);        ans = pow(a%mod,b,mod);        printf("%d\n",f[ans%mod]);    }    return 0;}
0 0
原创粉丝点击