HDU 3117 Fibonacci Numbers(斐波那契前后四位,打表+取对+矩阵快速幂)

HDU 3117 Fibonacci Numbers(斐波那契前后四位,打表+取对+矩阵快速幂)

ACM

题目地址:HDU 3117 Fibonacci Numbers

题意:

求第n个斐波那契数的前四位和后四位。

不足8位直接输出。

分析:

前四位有另外一题HDU 1568,用取对的方法来做的。

后四位可以用矩阵快速幂,MOD设成10000就行了。

代码:

/*
*  Author:      illuz <iilluzen[at]gmail.com>
*  Blog:        http://blog.csdn.net/hcbbt
*  File:        3117.cpp
*  Create Date: 2014-08-04 10:25:26
*  Descripton:
*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define repf(i,a,b) for(int i=(a);i<=(b);i++)

typedef long long ll;

const int N = 41;
const int SIZE = 2;        // max size of the matrix
const int MOD = 10000;

ll n;
ll tab[N];
double ans;

struct Mat{
    int n;
    ll v[SIZE][SIZE];    // value of matrix

    Mat(int _n = SIZE) {
        n = _n;
        memset(v, 0, sizeof(v));
    }

    void init(ll _v) {
        repf (i, 0, n - 1)
            v[i][i] = _v;
    }

    void output() {
        repf (i, 0, n - 1) {
            repf (j, 0, n - 1)
                printf("%lld ", v[i][j]);
            puts("");
        }
        puts("");
    }
} a, b;

Mat operator * (Mat a, Mat b) {
    Mat c(a.n);
    repf (i, 0, a.n - 1) {
        repf (j, 0, a.n - 1) {
            c.v[i][j] = 0;
            repf (k, 0, a.n - 1) {
                c.v[i][j] += (a.v[i][k] * b.v[k][j]) % MOD;
                c.v[i][j] %= MOD;
            }
        }
    }
    return c;
}

Mat operator ^ (Mat a, ll k) {
    Mat c(a.n);
    c.init(1);
    while (k) {
        if (k&1) c = a * c;
        a = a * a;
        k >>= 1;
    }
    return c;
}

double fib(int x) {
    return -0.5 * log(5.0) / log(10.0) + ( (double)n) * log((sqrt(5.0) + 1) / 2) / log(10.0);
}

void table() {
    // table
    tab[0] = 0;
    tab[1] = 1;
    repf (i, 2, 40)
        tab[i] = tab[i - 1] + tab[i - 2];
}

void pre4(int n) {
    ans = fib(n);
    ans -= floor(ans);
    ans = pow(10.0, ans);
    while (ans < 1000)
        ans *= 10;
    printf("%d", (int)ans);
}

void last4(int n) {
    a.init(0);
    a.v[0][0] = a.v[0][1] = a.v[1][0] = 1;

    b = a ^ (n - 1);
    printf("%04lld\n", b.v[0][0]);
}

int main() {
    table();
    while (~scanf("%lld", &n)) {
        if (n < 40) {
            printf("%lld\n", tab[n]);
            continue;
        }
        pre4(n);
        printf("...");
        last4(n);
    }
    return 0;
}

HDU 3117 Fibonacci Numbers(斐波那契前后四位,打表+取对+矩阵快速幂)

时间: 2024-08-17 00:16:41

HDU 3117 Fibonacci Numbers(斐波那契前后四位,打表+取对+矩阵快速幂)的相关文章

51nod 1242 斐波那契数列的第N项(矩阵快速幂)

1242 斐波那契数列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 斐波那契数列的定义如下: F(0) = 0 F(1) = 1 F(n) = F(n - 1) + F(n - 2) (n >= 2) (1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...) 给出n,求F(n),由于结果很大,输出F(n) % 1000000009的结果即可. Input 输入1个数n(1 <=

Codeforces Round #FF (Div. 2) E. DZY Loves Fibonacci Numbers(斐波那契的定理+线段树)

/* 充分利用了菲波那切数列的两条定理: ①定义F[1] = a, F[2] = b, F[n] = F[n - 1] + F[n - 2](n≥3). 有F[n] = b * fib[n - 1] + a * fib[n - 2](n≥3),其中fib[i]为斐波那契数列的第 i 项. ②定义F[1] = a, F[2] = b, F[n] = F[n - 1] + F[n - 2](n≥3). 有F[1] + F[2] + -- + F[n] = F[n + 2] - b 这题还有一个事实,

HDOJ/HDU 1250 Hat&#39;s Fibonacci(大数~斐波拉契)

Problem Description A Fibonacci sequence is calculated by adding the previous two members the sequence, with the first two members being both 1. F(1) = 1, F(2) = 1, F(3) = 1,F(4) = 1, F(n>4) = F(n - 1) + F(n-2) + F(n-3) + F(n-4) Your task is to take

hdu 3117 Fibonacci Numbers

点击此处即可传送到hdu 3117 **Fibonacci Numbers** Problem Description The Fibonacci sequence is the sequence of numbers such that every element is equal to the sum of the two previous elements, except for the first two elements f0 and f1 which are respectively

在sqlserver中做fibonacci(斐波那契)规律运算

--利用sqlserver来运算斐波那契规律 declare @number intdeclare @A intdeclare @B intdeclare @C int set @A=1 set @B=2 set @Number=3 select @[email protected][email protected] while(@Number<60) begin    set @[email protected][email protected]  if(@@ERROR<>0)  go

HDU 5863 cjj&#39;s string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但是 m 很小的时候 发现此题DP并不合适.于是想可能是某种组合数学的问题可以直接公式算 看到题解的我.恍然大悟.对于这种数据.可以考虑一下矩阵快速幂优化的DP 首先要想到线性递推的 DP 式子 最直观的想法就是 dp[i][j] = 到第 i 个位置为止.前面最长匹配长度为 j 的方案数 但是如果仔

HDU 3117 Fibonacci Numbers(矩阵快速幂+公式)

题目地址:HDU 3117 对于后四位可以用矩阵快速幂快速求出来,但前四位就没办法了.要知道斐波那契数列是有通项公式的,所以只能通过通项公式来求前四位,但公式不能求后四位,因为公式使用浮点数求的,精度显然不够,求前四位要用到对数. 通项公式为: f(n)=1/sqrt(5)(((1+sqrt(5))/2)^n+((1-sqrt(5))/2)^n) 假设F[n]可以表示成 t * 10^k(t是一个小数),那么对于F[n]取对数log10,答案就为log10 t + K,此时很明显log10 t<

GameTheory(二):Fibonacci Game(斐波那契博弈)

本质描述: 有n个物品,游戏双方轮流取物品,规则为: 1.先手不能在第一次把所有的物品取完 2.之后每次可以取的物品个数为[ 1 , 2 * 对手取的数量] 轮到某人取,这个人没东西取就是输了. 结论: 当n为斐波那契数的时候,先手处于必败态 分析一下: 我们可以看到,这个博弈跟Bash Game不同,这个规则是动态的.证明这个Game要用到Zeckendorf(齐肯多夫定理):任何正整数都可以表示成若干个不连续的斐波那契数(1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 ,

Fibonacci series(斐波纳契数列)的几种常见实现方式

费波那契数列的定义: 费波那契数列(意大利语:Successione di Fibonacci),又译费波拿契数.斐波那契数列.斐波那契数列.黄金分割数列. 在数学上,费波那契数列是以递归的方法来定义: (n≧2) 用文字来说,就是费波那契数列由0和1开始,之后的费波那契系数就由之前的两数相加. 首几个费波那契系数是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233-- 特别指出:0不是第一项,而是第零项. 下面是费波那契数列的几种常见编程实现: