快速幂的初步学习

快速幂的用处很多,常见的问题有快速幂取模和矩阵快速幂,一般的问题套用模板就可以。快速幂的思想是分治,类似于二分,所以时间复杂度是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\n",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\n",(c.mat[0][1])%mod);
   }
    return 0;
}
posted @ 2016-03-22 17:10  HARD_UNDERSTAND  阅读(150)  评论(0编辑  收藏  举报