POJ3070 Fibonacci(矩阵快速幂加速递推)【模板题】

题目链接:传送门

题目大意:

  求斐波那契数列第n项F(n)。

  (F(0) = 0, F(1) = 1, 0 ≤ n ≤ 109

思路:

  用矩阵乘法加速递推。

算法竞赛进阶指南的模板:

#include <iostream>
#include <cstring>

using namespace std;
const int MOD = 10000;

void mul(int f[2], int base[2][2]) {
    int c[2];
    memset(c, 0, sizeof c);
    for (int j = 0; j < 2; j++) {
        for (int k = 0; k < 2; k++) {
            c[j] = (c[j] + 1LL * f[k] * base[k][j]) % MOD;
        }
    }
    memcpy(f, c, sizeof c);
}
void mulself(int base[2][2]) {
    int c[2][2];
    memset(c, 0, sizeof c);
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            for (int k = 0; k < 2; k++)
                c[i][j] = (c[i][j] + 1LL*base[i][k]*base[k][j]) % MOD;
    memcpy(a, c, sizeof c);
}

int main()
{
    int n;
    while (cin >> n && n != -1) {
        int f[2] = {0, 1};
        int base[2][2] = {{0, 1}, {1, 1}};
        for (; n; n >>= 1) {
            if (n & 1) mul(f, base);
            mulself(base);
        }
        cout << f[0] << endl;
    }
    return 0;
}

蒟蒻的模板:

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;
typedef long long ll;
const int MOD = 1e4;
const int MAXN = 2;
struct Matrix{
    int mat[MAXN][MAXN];
    Matrix operator * (Matrix const& b) const {
        Matrix res;
        memset(res.mat, 0, sizeof res.mat);
        for (int i = 0; i < MAXN; i++)
            for (int j = 0; j < MAXN; j++)
                for (int k = 0; k < MAXN; k++)
                    res.mat[i][j] = (res.mat[i][j] + this->mat[i][k] * b.mat[k][j])%MOD;
        return res;
    }
}base, F0, FN;
Matrix fpow(Matrix base, ll n) {
    Matrix res;
    memset(res.mat, 0, sizeof res.mat);
    for (int i = 0; i < MAXN; i++)
        res.mat[i][i] = 1;
    while (n) {
        if (n&1) res = res*base;
        base = base * base;
        n >>= 1;
    }
    return res;
}
void init()
{
    base.mat[0][0] = 0; base.mat[0][1] = 1;
    base.mat[1][0] = 1; base.mat[1][1] = 1;
    memset(F0.mat, 0, sizeof F0.mat);
    F0.mat[0][0] = 1; F0.mat[0][1] = 1;
}

int main()
{
    int N;
    while (cin >> N) {
        if (N == -1)
            break;
        init();
        FN = fpow(base, N);
        cout << FN.mat[0][1] << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/9955571.html

时间: 2024-12-10 20:23:32

POJ3070 Fibonacci(矩阵快速幂加速递推)【模板题】的相关文章

HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers

矩阵快速幂优化递推总结

RT,主要总结一下矩阵的求法. 首先能用矩阵快速幂优化的递推类型是f[n]=5f[n-3]+6f[n-2]+2f[n-1]+n^2+n+8之类的 也就是说递推是线性递推且f[n-i]前面的系数是常数,可以含有与n有关的多项式,也可以含有常数的这种递推,下面总结一下矩阵的写法: 先考虑最简单的常数,我们其实可以忽略常数,因为顶多在没有常数的矩阵外面加一行一列就行了 以f[n]=2f[n-1]+6f[n-2]+5f[n-3]+n^2+n为例 先写迭代的矩阵,一般可以写成一行,右边有几项写几项 {f[

[HIHO1143]骨牌覆盖问题&#183;一(矩阵快速幂,递推)

题目链接:http://hihocoder.com/problemset/problem/1143 这个递推还是很经典的,结果是斐波那契数列.f(i) = f(i-1) + f(i-2).数据范围太大了,应该用快速幂加速下. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 10 ┛┗┛┗┛┃ 11 ┓┏┓┏┓┃ 12 ┛┗┛┗┛┃ 13

ZOJ 3690 &amp; HDU 3658 (矩阵快速幂+公式递推)

ZOJ 3690 题意: 有n个人和m个数和一个k,现在每个人可以选择一个数,如果相邻的两个人选择相同的数,那么这个数要大于k 求选择方案数. 思路: 打表推了很久的公式都没推出来什么可行解,好不容易有了想法结果WA到天荒地老也无法AC.. 于是学习了下正规的做法,恍然大悟. 这道题应该用递推 + 矩阵快速幂. 我们设F(n) = 有n个人,第n个人选择的数大于k的方案数: G(n) = 有n个人,第n个人选择的数小于等于k的方案数: 那么递推关系式即是: F(1)=m?k,G(1)=k F(n

POJ 3734 Blocks(矩阵快速幂加递推)

Blocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6133   Accepted: 2931 Description Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent boy, he starts to think of a math problem of paint

矩阵快速幂 ——(递推表达式)

矩阵快速幂 首先知道矩阵 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合: 矩阵乘法: 定义:设A为 m×p 的矩阵,B为 p×n 的矩阵,那么称 m×n 的矩阵C为矩阵A与B的乘积,记作 C=A×B ,其中矩阵C中的第 i 行第 j 列元素可以表示为: 知道矩阵乘法之后,比如菲波那切数列就是一个递推式, F(n)=F(n-1)+F(n-2); 因为矩阵乘法,所以 设 矩阵 A为 矩阵 B 为 则  A*B  则为    F(n)=        F(n-1)*1+F(n-2)*1

hiho 1143 矩阵快速幂 求递推式

题目链接: hihocoder 1143 思路见题目上 快速幂模板: // m^n % k int quickpow(int m,int n,int k) { int b = 1; while (n > 0) { if (n & 1) b = (b*m)%k; n = n >> 1 ; m = (m*m)%k; } return b; } 题解: #include<iostream> #include<cstdio> #include<cstring

题目1081:递推数列 (矩阵快速幂解递推式)

题目1081:递推数列 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5885 解决:800 题目描述: 给定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q.这里n >= 2. 求第k个数对10000的模. 输入: 输入包括5个整数:a0.a1.p.q.k. 输出: 第k个数a(k)对10000的模. 样例输入: 20 1 1 14 5 样例输出: 8359 来源: 2009年清华大学计算机研究生机试真题 1 #include<stdio.h> 2 #

POJ3070:Fibonacci(矩阵快速幂模板题)

http://poj.org/problem?id=3070 #include <iostream> #include <string.h> #include <stdlib.h> #include <cstdio> #include <algorithm> #define mod 10000 using namespace std; struct m { int a[3][3]; } init,res; int n; m Mult(m x,m