zoukankan      html  css  js  c++  java
  • POJ3070矩阵快速幂简单题

    题意:
          求斐波那契后四位,n <= 1,000,000,000.
    思路:
           简单矩阵快速幂,好久没刷矩阵题了,先找个最简单的练练手,总结下矩阵推理过程,其实比较简单,关键是能把问题转换成矩阵的题目,也就是转换成简单加减地推式,下面说下怎么样根据递推式构造矩阵把,这个不难,我的习惯是在中间插矩阵,就是比如斐波那契
    a[n] = a[n-1] + a[n-2];


    我的习惯是这样,首先要知道这个式子是有连续的两个项就可以推出第三个项
    那么 
         
    a1 a2   0  1  a2  a3   这样就直接出来了中间矩阵,然后快速幂处理,这个是          
            1  1           最简单的了,一般都是要想办法各种转换,然后在构造式子
                           然后在快速幂,还有注意,矩阵可以把最下面那个循环拿到上面

                           然后通过if(mat[i][k])来优化,我下面的用了,这个要看0出现                       的多不多(比较重要),还有可以通过调换循环位置(这个是底                       层优化,不在算法范围之内)优化,推荐一个好题,杭电上有个                       叫 什么什么233的那个,记得当时做那个题做的比较爽。


    #include<stdio.h>
    #include<string.h>
    
    #define MOD 10000
    
    typedef struct
    {
        int mat[3][3];
    }M;
    
    M matM(M a ,M b)
    {
        M c;
        memset(c.mat ,0 ,sizeof(c.mat));
        for(int k = 1 ;k <= 2 ;k ++)
        for(int i = 1 ;i <= 2 ;i ++)
        if(a.mat[i][k])
        for(int j = 1 ;j <= 2 ;j ++)
        c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;
        return c;
    }
    
    M qPowMat(M a ,int b)
    {
        M c;
        memset(c.mat ,0 ,sizeof(c.mat));
        for(int i = 1 ;i <= 2 ;i ++)
        c.mat[i][i] = 1;
        while(b)
        {
            if(b&1) c = matM(c ,a);
            a = matM(a ,a);
            b >>= 1;
        }
        return c;
    }
    
    int main ()
    {
        int n ,i;
        M star ,ans;
        star.mat[1][1] = 0;
        star.mat[1][2] = star.mat[2][1] = star.mat[2][2] = 1;
        while(~scanf("%d" ,&n) && n != -1)
        {
            if(n == 0)
            {
                printf("0
    ");
                continue;
            }
            if(n == 1)
            {
                printf("1
    ");
                continue;
            }
    
            ans = qPowMat(star ,n);
    
            printf("%d
    " ,(0 * ans.mat[1][1] + 1 * ans.mat[2][1]) % MOD);
        }
        return 0;
    }
    


  • 相关阅读:
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十一)
    install ubuntu on Android mobile phone
    Mac OS, Mac OSX 与Darwin
    About darwin OS
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十)
    Linux下编译安装qemu和libvirt
    libvirt(virsh命令总结)
    深入浅出 kvm qemu libvirt
    自然语言交流系统 phxnet团队 创新实训 项目博客 (九)
    自然语言交流系统 phxnet团队 创新实训 项目博客 (八)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062442.html
Copyright © 2011-2022 走看看