POJ 3070 Fibonacci
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10530 | Accepted: 7484 |
Description
In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …
An alternative formula for the Fibonacci sequence is
.
Given an integer n, your goal is to compute the last 4 digits of Fn.
Input
The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.
Output
For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).
Sample Input
0
9
999999999
1000000000
-1
Sample Output
0
34
626
6875
Hint
As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by
.
Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:
.
#include <iostream> #include <cstdio> #include <cstring> #define REP(i, s, n) for(int i = s; i <= n; i ++) #define REP_(i, s, n) for(int i = n; i >= s; i --) #define MAX_N 3 #define mod 10000 using namespace std; int a, b, n; struct node{ int Mtx[MAX_N][MAX_N]; }tmp; node operator+(node a,node b){ node c; REP(i, 1, 2) REP(j, 1, 2){ c.Mtx[i][j] = a.Mtx[i][j] + b.Mtx[i][j]; } return c; } node operator*(node a,node b){ node c; REP(i, 1, 2) REP(j, 1, 2){ c.Mtx[i][j] = 0; REP(k, 1, 2) c.Mtx[i][j] = (c.Mtx[i][j] + a.Mtx[i][k] * b.Mtx[k][j]) % mod; } return c; } node operator^(node a,int k){ if(k == 0){ memset(a.Mtx, 0, sizeof(a.Mtx)); REP(i, 1, 2) a.Mtx[i][i] = 1; return a; } if(k == 1) return a; node c = a ^ (k >> 1); if(k & 1) return c * c * a; return c * c; } int main(){ while(scanf("%d", &n) != EOF){ if(n == -1) break; if(n == 0) { cout << 0 << endl; continue; } else { tmp.Mtx[1][1] = 1; tmp.Mtx[1][2] = 1; tmp.Mtx[2][1] = 1; tmp.Mtx[2][2] = 0; tmp = tmp ^ n; cout << tmp.Mtx[1][2] << endl; } } return 0; }