快速幂的初步学习

来源:互联网 发布:php session redis 编辑:程序博客网 时间:2024/06/05 05:00

快速幂的用处很多,常见的问题有快速幂取模和矩阵快速幂,一般的问题套用模板就可以。快速幂的思想是分治,类似于二分,所以时间复杂度是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;}
0 0
原创粉丝点击