2018年东北农业大学春季校赛-wyh的数列

时间限制:C/C++ 1秒,其他语言2秒
空间限制: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

题解 :费波那西数列 对 C 求余,那么就存在循环节,当 f[i]==f[1]&&f[i-1]==f[0]            时,那么 i-1 便是一个循环节周期(T),然后利用快速幂 对 T 求余,求出                a^b 对应在T内的第几位,然后带入f[]数组中;

注意 :开 long long 会有溢出现象,需要用unsigned long long ;

           long long:  -9223372036854775808 ~ +9223372036854775807

                unsigned long long: 最大:18446744073709551615

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
typedef unsigned long long ll;
ll f[1000100]={0,1};
ll fun(int c){
ll h;
for(int i=2;;i++){
f[i]=(f[i-1]+f[i-2])%c;
if(f[i]==f[1]&&f[i-1]==f[0]){
h=i;
break;
}
}
return h-1;
}

ll po_w(ll a,ll b,ll c){
ll ans=1;
a%=c;
while(b){
if(b&1)
  ans=ans*a%c;
b>>=1;
a=a*a%c;
}
return ans;
}

int main(){
int t;
ll a,b,c;
scanf("%d",&t);
while(t--){
scanf("%llu %llu %llu",&a,&b,&c);
ll g=fun(c);
cout<<f[po_w(a,b,g)]<<endl;
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/black_horse2018/article/details/79864521