1. 程式人生 > >UVA 11582 Colossal Fibonacci Numbers!(數論)

UVA 11582 Colossal Fibonacci Numbers!(數論)

思路: 所有計算都對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; }