Fibonacci

时间限制: 1 Sec  内存限制: 128 MB

题目描述

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.
 

 

输入

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.

 

 

输出

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).

 

 

样例输入

复制样例数据

0
9
999999999
1000000000
-1

样例输出

0
34
626
6875

 

提示

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 <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>

typedef long long LL;
using namespace std;

LL n;
const long long mod = 10000;

struct node
{
	LL m[3][3];
};

node mul(node x, node y){
	node res;
	memset(res.m, 0, sizeof(res.m));
	for (int i = 1; i <= 2; i++){
		for (int j = 1; j <= 2; j++){
			for (int k = 1; k <= 2; k++){
				res.m[i][j] = (res.m[i][j] + x.m[i][k] * y.m[k][j] % mod) % mod;
			}
		}
	}
	return res;
}

node pow_M(node x, LL num){
	node res;
	memset(res.m, 0, sizeof(res.m));
	for (int i = 1; i <= 2; i++) res.m[i][i] = 1;
	while(num){
		if(num & 1) res = mul(res, x);
		x = mul(x, x);
		num >>= 1LL;
	}
	return res;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);

	while(scanf("%lld", &n) == 1){
		if(n == -1) break;
		if(n == 0){
			printf("0\n");
			continue;
		}else if(n == 1 || n == 2){
			printf("1\n");
		}
		node M;
		M.m[1][1] = 1, M.m[1][2] = 1, M.m[2][1] = 1, M.m[2][2] = 0;
		M = pow_M(M, n - 2);
		LL p = (M.m[1][1] + M.m[1][2]) % mod, ans = 0, num = 0, f = 1;
		while(p){
			if(++num > 4) break;
			ans += p % 10 * f;
			f *= 10;
			p /= 10;
		}
		printf("%lld\n", ans % mod);
	}

	return 0;
}
/**/