巨大的斐波那契数
The i'th Fibonacci number f (i) is recursively defined in the following way:
- f (0) = 0 and f (1) = 1
- f (i+2) = f (i+1) + f (i) for every i ≥ 0
Your task is to compute some values of this sequence.
Input begins with an integer t ≤ 10,000, the number of test cases. Each test case consists of three integers a,b,n where 0 ≤ a,b < 264 (a andb will not both be zero) and 1 ≤ n ≤ 1000.
For each test case, output a single line containing the remainder of f (ab) upon division by n.
Sample input
3 1 1 2 2 3 1000 18446744073709551615 18446744073709551615 1000
Sample output
1 21 250
题意:
输 入两个非负整数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取模,余数只有n种,所以最多n^2项序列就开始重复,所以问题转化成了求周期然后大整数取模。
小于2^64的数要用unsigned long long。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn=1000+5; int m[maxn],n; typedef unsigned long long ULL; unsigned long long a,b; unsigned long long f[maxn][3100]; int pow_mod(ULL a,ULL b,int n) { if(b==0) return 1; int x=pow_mod(a,b/2,n); unsigned long long ans=(unsigned long long )x*x%n; if(b%2==1) ans=ans*a%n; return (int)ans; } int main() { for(n=2;n<=1000;n++) { f[n][0]=0,f[n][1]=1; for(int i=2;;i++) { f[n][i]=(f[n][i-1]+f[n][i-2])%n; if(f[n][i]==1&&f[n][i-1]==0) { m[n]=i-1; break; } } } int t; scanf("%d",&t); while(t--) { scanf("%llu%llu%d",&a,&b,&n); if(n==1||a==0) printf("0 "); else printf("%d ",f[n][pow_mod(a%m[n],b,m[n])]); } return 0; }