POJ-3070 Fibonacci (矩阵快速幂)

Fibonacci
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 17928 Accepted: 12470

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

题目意思很清楚了 直接套模板就可以了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#define  _rep(i, a, b) for(int i = a; i <= b; i++)
#define  _for(i, a, b) for(int i = a; i < b; i++)
#define  M_sel *this
using namespace std;

typedef vector<int> vec_int;
typedef vector<vec_int> mat_int;
typedef long long ll;
const int Maxn = 1010;
const int Maxm = 1010;
const int Mod = 10000;

struct Matrix {
	int n, m;
	mat_int a;
	Matrix(int n = 0, int  m= 0) {
		this->n = n; this->m = m;
		vec_int tmp;
		tmp.assign(m, 0);
		_for(i, 0, n)
			a.push_back(tmp);
	}
	void clear(){
		_for(i, 0, n)
			a.clear();
		n = m = 0;
	}
	Matrix operator + (const Matrix &b) const {
		Matrix tmp(n, m);
		_for(i, 0, n) 
			_for(j, 0, m)
				tmp.a[i][j] = a[i][j] + b.a[i][j];
		return tmp;
	}
	Matrix operator - (const Matrix &b) const {
		Matrix tmp(n, m);
		_for(i, 0, n)
			_for(j, 0, m)
				tmp.a[i][j] = a[i][j] - b.a[i][j];
		return tmp;
	}
	Matrix operator * (const Matrix &b) const {
		Matrix tmp(n, b.m);
		_for(i, 0, n) 
			_for(j, 0, b.m) 
				_for(k, 0, m) 
					tmp.a[i][j] = (tmp.a[i][j] + a[i][k] * b.a[k][j] % Mod) % Mod;//Mod在外部设置,主要是为了方便求快速幂;
		return tmp;
	}
	Matrix pow(ll b) {
		Matrix tmp(n, m);
		_for(i, 0, n)
			tmp.a[i][i] = 1;
		while (b) {
			//if (b & 1) tmp = (*this) * tmp;
			//(*this) = (*this) * (*this);
			if (b & 1) tmp = M_sel * tmp; //指针和乘号放在一起很难受, 在上面开了个宏定义
			M_sel = M_sel * M_sel;
			b >>= 1;
		}
		return tmp;
	}
};
ll n;
int main() {
#ifdef ZTZTMS
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif
	Matrix A(2, 2);
	A.a[0][0] = 1; A.a[0][1] = 1;
	A.a[1][0] = 1; A.a[1][1] = 0;
	while (~scanf("%lld", &n) && n >= 0) {
		Matrix ans = A.pow(n);
		printf("%d\n", ans.a[1][0]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值