• 集训第六周 矩阵快速幂 K题


    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


    1.使用一个结构体存下矩阵,再写一个二维矩阵乘法函数

    2.然后求[1 1 1 0]的n次方?当然不是。

    注意:0 ≤ n ≤ 1,000,000,000

    如果这样直接乘以n次肯定会超时

    可以使用二进制求快速幂

    利用二进制求指数幂

    举例:

    3 ^ 999 = 3 * 3 * 3 * … * 3

    直接乘要做998次乘法。但事实上可以这样做,先求出2^k次幂:

    3 ^ 2 = 3 * 3

    3 ^ 4 = (3 ^ 2) * (3 ^ 2)

    3 ^ 8 = (3 ^ 4) * (3 ^ 4)

    3 ^ 16 = (3 ^ 8) * (3 ^ 8)

    3 ^ 32 = (3 ^ 16) * (3 ^ 16)

    3 ^ 64 = (3 ^ 32) * (3 ^ 32)

    3 ^ 128 = (3 ^ 64) * (3 ^ 64)

    3 ^ 256 = (3 ^ 128) * (3 ^ 128)

    3 ^ 512 = (3 ^ 256) * (3 ^ 256)

    再相乘:

    3 ^ 999

    = 3 ^ (512 + 256 + 128 + 64 + 32 + 4 + 2 + 1)

    = (3 ^ 512) * (3 ^ 256) * (3 ^ 128) * (3 ^ 64) * (3 ^ 32) * (3 ^ 4) * (3 ^ 2) * 3

    把999转为2进制数:1111100111,其个位就是要乘的数。

    1   pow ← 1

    2   while (n > 0)

    3      do if (n mod 2 = 1)

    4            then pow ← pow * x

    5        x ← x * x

    6        n ← n / 2

    7      return pow

    #include"iostream"
    #include"cstdio"
    using namespace std;
    
    typedef struct
    {
        int m[2][2];
    }node;
    
    node work(node a,node b)
    {
        node c;
        c.m[0][0]=(a.m[0][0]*b.m[0][0]+a.m[0][1]*b.m[1][0])%10000;
        c.m[0][1]=(a.m[0][0]*b.m[0][1]+a.m[0][1]*b.m[1][1])%10000;
        c.m[1][0]=(a.m[1][0]*b.m[0][0]+a.m[1][1]*b.m[1][0])%10000;
        c.m[1][1]=(a.m[1][0]*b.m[0][1]+a.m[1][1]*b.m[1][1])%10000;
        return c;
    }
    
    void caculate(int c)
    {
        node ans,base;
        base.m[0][0]=base.m[1][0]=base.m[0][1]=1;
        base.m[1][1]=0;
        ans.m[0][0]=ans.m[1][1]=1;
        ans.m[0][1]=ans.m[1][0]=0;
        while(c)
        {
            if(c&1) ans=work(ans,base);
            base=work(base,base);
            c>>=1;
        }
        cout<<ans.m[1][0]<<endl;
    }
    
    int main()
    {
        int n;
        while(cin>>n&&n>=0)
        {
            caculate(n);
        }
    }
    View Code
    
    
  • 相关阅读:
    82.Java集合学习之Collections与Arrays
    81.Java集合之TreeMap
    vuex 封装
    async awiat
    纯前端导入导出
    使用node搭建服务器
    node.js
    axios请求拦截器
    数据结构学习第十九天
    数据结构学习第十八天
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/4750366.html
Copyright © 2020-2023  润新知