hdu 4549 M斐波那契數列
阿新 • • 發佈:2019-01-29
f(n)表示斐波那契數列的第n項
F(n) = a^f(n-1)*b^f(n) 這個推一下就知道了
然後f(n)可以用矩陣快速冪求
1 1 f(n+1) f(n)
1 0 的n次冪 = f(n) f(n-1) 就行了(至於為什麼有這個自己度娘把。。)
但關鍵點在於f(n)可能很大 a^f(n-1)不好求
但是我們有費馬小定理 a^p-1 = 1(mod p) p是質數 1000000007是質數 所以a^1000000006=1 (mod 1000000007)
所以我們只需要求f(n-1)%1000000006的值就行了 然後答案就是a^(f(n-1)%1000000006)*b^((f(n)%1000000006))%1000000007
附一個Java的程式碼= = 最近在寫Java專案,一直開的eclipse 沒寫C++的 不過思路是一樣的。。。
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.StringTokenizer; public class Main { private static InputReader in = new InputReader(); private static final int MOD = 1000000007; private static final long[][] gen = { { 1, 1 }, { 1, 0 } }; private static long pow(long n, long a) { if (a == 0) return 1; if (a == 1) return n; long ret = pow(n, a / 2); ret *= ret; ret %= MOD; if (a % 2 != 0) ret = ret * n; ret %= MOD; return ret; } private static long[][] quick(long[][] m, int a) { if (a == 0) { long[][] ret = new long[2][2]; ret[0][0] = ret[1][1] = 1; ret[0][1] = ret[1][0] = 0; return ret; } if (a == 1) return gen; else { long[][] mm = quick(gen, a / 2); long[][] ret = new long[2][2]; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) { ret[i][j] = 0; for (int k = 0; k < 2; k++) { ret[i][j] += mm[i][k] * mm[k][j]; ret[i][j] %= MOD - 1; } } if (a % 2 != 0) { long rett[][] = new long[2][2]; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { rett[i][j] += ret[i][k] * gen[k][j]; rett[i][j] %= MOD - 1; } } return rett; } return ret; } } public static void main(String[] args) { int a, b, n; try { while (true) { a = in.nextInt(); b = in.nextInt(); n = in.nextInt(); if (n == 0) { System.out.println(a); } else if (n == 1) { System.out.println(b); } else { long[][] ret = quick(gen, n - 1); long ans = pow(b, ret[0][0]); ans *= pow(a, ret[0][1]); ans %= MOD; System.out.println(ans); } } } catch (Exception e) { } } } class InputReader { BufferedReader br; StringTokenizer st; public InputReader(String s) { try { br = new BufferedReader(new FileReader(s)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public InputReader() { br = new BufferedReader(new InputStreamReader(System.in)); } String nextToken() { while (st == null || !st.hasMoreElements()) { try { st = new StringTokenizer(br.readLine()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return st.nextToken(); } String nextLine() { try { return br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } int nextInt() { return Integer.parseInt(nextToken()); } long nextLong() { return Long.parseLong(nextToken()); } double nextDouble() { return Double.parseDouble(nextToken()); } }