牛客网 wyh的数列(循环节+快速幂)
链接:https://www.nowcoder.com/acm/contest/93/K
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
wyh学长特别喜欢斐波那契数列,F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n>=2)
一天他突发奇想,想求F(a^b)%c
输入描述:
输入第一行一个整数T(1<=T<=100),代表测试组数
接下来T行,每行三个数 a,b,c (a,b<=2^64) (1<c<1000)
输出描述:
输出第a^b项斐波那契数对c取余的结果
示例1
输入
3 1 1 2 2 3 1000 32122142412412142 124124124412124 123
输出
1 21 3
分析:本题的求斐波拉契的范围很大,但取模较小,所以一定会存在循环节,
如果出现相邻两项与最初两项相同的时候,即找到循环节。
需要注意的是本题输入的范围超过了long long
所以需要用unsigned long long
代码如下:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long LL; LL t,a,b,c,xun; LL f[1000100]; LL quick_pow(LL a,LL b) { LL ans=1; a%=xun; while(b>0) { if(b&1) ans=(ans*a)%xun; b>>=1; a=(a*a)%xun; } return ans; } int main() { ios::sync_with_stdio(false); cin>>t; while(t--) { cin>>a>>b>>c; f[0]=0;f[1]=1; for(int i=2;i<=1000100;i++) { f[i]=(f[i-1]+f[i-2])%c; if(f[i-1]==0&&f[i]==1) { xun=i-1; break; } } cout<<f[quick_pow(a,b)]<<endl; } return 0; }