zoukankan      html  css  js  c++  java
  • 快速幂的初步学习

    快速幂的用处很多,常见的问题有快速幂取模和矩阵快速幂,一般的问题套用模板就可以。快速幂的思想是分治,类似于二分,所以时间复杂度是O(n)。
    推荐一篇很好的文章:http://blog.csdn.net/cambridgeacm/article/details/7703809

    FZU 1752 A^Bmoc C
    题意:Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63).
    分析
    直接明了的快速幂乘,但是由于a很大,所以需要计算a*b%c时,将b按二进制分解
    (这题是以前写的)

    #include <iostream>
    #include <cstring>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    ll mul(ll a,ll b,ll c)//计算a*b%c,将b按二进制分解
    {
        ll res=0;
        for(;b;b>>=1){
            if(b&1){
                res+=a;
                while(res>=c)res-=c;
            }
            a<<=1;
            while(a>=c)a-=c;
        }
        return res;
    }
    ll qmod(ll a,ll b,ll c)//幂乘,将b分解为2进制
    {
        ll res=1;
        for(;b;b>>=1){
            if(b&1)res=mul(a,res,c);
            a=mul(a,a,c);
        }
        return res;
    }
    int main()
    {
        ll a,b,c;
        while(scanf("%I64d%I64d%I64d",&a,&b,&c)!=EOF){
            printf("%I64d
    ",qmod(a%c,b,c));
        }
        return 0;
    }
    

    poj 3070 矩阵快速幂
    题意:
    给你n,求Fibonacci数列的第n项的后四位是多少?
    分析
    由于这道题已经告诉你要用矩阵快速幂做了,而且给出了公式,所以直接快速幂就好。
    一般的用到矩阵快速幂的题,会让你推出一个公式,然后化成矩阵的形式,用矩阵快速幂求解。

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    typedef long long ll;
    const int mod=10000;
    const int N = 2;
    
    struct Mat {
        int mat[N][N];
    };
    int n=2, m;
    int A,B;
    
    Mat mul(Mat a, Mat b) {
        Mat c;
        memset(c.mat, 0, sizeof(c.mat));
        int i, j, k;
        for(k = 0; k < n; ++k) {
            for(i = 0; i < n; ++i) {
                for(j = 0; j < n; ++j) {
                    c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
                    c.mat[i][j]%=mod;
                }
            }
        }
        return c;
    }
    
    Mat qmod(Mat a, int k) {
        Mat c;
        int i, j;
        for(i = 0; i < n; ++i)
            for(j = 0; j < n; ++j)
                c.mat[i][j] = (i == j);
    
        for(; k; k >>= 1) {
            if(k&1) c = mul(a,c);
            a = mul(a,a);
        }
        return c;
    }
    
    int main()
    {
       int n;
       while(~scanf("%d",&n)){
            if(n==-1)break;
            Mat a;
            a.mat[0][0]=a.mat[0][1]=a.mat[1][0]=1;;
            a.mat[1][1]=0;
            Mat c=qmod(a,n);
            printf("%d
    ",(c.mat[0][1])%mod);
       }
        return 0;
    }
    
  • 相关阅读:
    动态存储区(堆)、动态存储区(栈)、静态存储区、程序代码区
    auto, extern, register, static
    #include <iomanip>
    use
    ZooKeeper某一QuorumPeerMain挂了
    python 中的 字符串 列表 元祖 字典
    JAVA的23种设计模式
    spark job分析
    Spark1
    SQL三大范式
  • 原文地址:https://www.cnblogs.com/01world/p/5651258.html
Copyright © 2011-2022 走看看