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;
    }
    
  • 相关阅读:
    【转】@JoinColumn 详解
    Hibernate的getTransaction()和beginTransaction()
    什么是事务(transaction)?它有什么好处
    tomcat安装不成功.提示:failed to install tomcat6 service ,check your setting and permissions
    java面试题02
    JAVA面试题01
    浅析=======Struts2之==========valueStack
    Hibernate映射文件
    Hibernate核心配置文件
    激活Microsoft Word 2010
  • 原文地址:https://www.cnblogs.com/01world/p/5651258.html
Copyright © 2011-2022 走看看