UVA 11582 Colossal Fibonacci Numbers!(數論)
阿新 • • 發佈:2018-12-10
思路: 所有計算都對n取模。餘數存在週期規律,最多n2項就會重複。然後快速冪判斷目標處於週期的那個位置即可。注意用cin,而不是scanf,之前這裡改了好久。
AC code:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e3 + 100;
typedef unsigned long long LL;
int f[maxn*maxn];
LL a = 0,b = 0;
int n = 0,mod = 0;
int T = 0 ;
void pre_solve(){
for(int i = 2;i < n * n + 100;++i){
f[i] = (f[i-1] + f[i-2]) % n;
if(f[i] == f[1] && f[i-1] == f[0]){
mod = i - 1;//週期迴圈規律,像這樣資料規模很大的,很可能存在某種規律
break;//不妨列印幾個例子觀察一下規律
}
//mod = 2;
}
//mod = n * n + 101;
}
LL solve(){
LL ans = 1 ;
a = a % mod;
while(b > 0){
if(b & 1){
ans = (a % mod )* (ans % mod) % mod;
//ans = (a % mod) * ans % mod;
}
a = (a % mod) * (a % mod) % mod ;
//a = a % mod * a;
b >>= 1;
}
return ans;
}
LL mod_pow(LL x,LL n){//學會自己推導遞迴式,有點抽象
if(n == 0){//終止條件
return 1;
}
LL res = mod_pow((x % mod) * (x % mod) % mod ,n / 2);//遞迴表示式
if(n & 1){//偶數遞迴下去除以2,奇數的1,要新增
res = (res % mod) * (x % mod) % mod;
}
return res;
}
LL mod_pow1(LL a, LL p,LL mod) {
if(p == 0) return 1;
LL ans = mod_pow1(a, p/2,mod);
ans = ans * ans % n;
if(p%2 == 1) ans = ans * a % n;
return ans;
}
int main(){
f[0] = 0; f[1] = 1;
//scanf("%d",&T);
cin >> T;
while(T--){
//scanf("%I64d %I64d %d",&a,&b,&n);
cin >> a >> b >> n;
if(n == 1){
cout << "0" << endl;
continue;
}
pre_solve();
//int ans = (int)mod_pow1(a % mod,b,(LL)mod);
//int ans = solve();
int ans = mod_pow(a,b);
//printf("%d\n",f[ans]);
cout << f[ans] << endl;
}
return 0;
}