码迷,mamicode.com
首页 > 其他好文 > 详细

[模板]快速幂,矩阵快速幂

时间:2018-03-03 15:32:31      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:pre   自乘   int   names   blog   power   set   pow   org   

Part 1 快速幂

朴素的O(n)算法过慢,又存不下过大的变量,所以考虑将指数二进制化,每次右移一位,底数随着自乘,就有了O(logn)的算法。

大数通常需要结果对P取模, 为了避免中间变量溢出,我们可以边取模边计算,有如下等式:

  • (a*b)%p=((a%p)*(b%p))%p

  • 代码如下:

    #include<iostream>
    using namespace std;
    long long b, p, k;
    long long quick_power(long long a, long long b, long long c)
    {
    long long res = 1;
    a %= c;
    while (b != 0)
    {
        if (b & 1)res = res*a%c;
        b = b >> 1;
        a = a*a%c;
    }
    return res;
    }
    int main()
    {
    cin >> b >> p >> k;
    cout << b << "^" << p << " mod " << k << "=" << quick_power(b, p, k);
    return 0;
    }

Part 2 矩阵快速幂

在矩阵快速幂之前,我们需要先了解下矩阵乘法:https://en.wikipedia.org/wiki/Matrix_multiplication

与快速幂类似,再重载结构体的乘号即可。

  • 代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 101
    using namespace std;
    typedef long long ll;
    const ll p=1000000007;
    ll N,k;
    struct matrix{
    ll a[maxn][maxn];
    matrix(){memset(a,0,sizeof(a));}
    matrix operator *(matrix b)
    {
        matrix ret;
        for(int i=1;i<=N;++i)
            for(int j=1;j<=N;++j)
                for(int k=1;k<=N;++k)
                    ret.a[i][j]=(ret.a[i][j]+(a[i][k]*b.a[k][j])%p)%p;
        return ret;     
    }
    void print()
    {
        for(int i=1;i<=N;++i){
            for(int j=1;j<=N;++j)
                printf("%d ",a[i][j]);
            putchar('\n');
        }
    }
    };
    matrix quick_power(matrix b,ll k)
    {
    matrix ans;
    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
            ans.a[i][j]=(i==j)?1:0;
    while(k){
        if(k&1)ans=ans*b;
        k>>=1;
        b=b*b;
    }
    return ans;
    }
    int main()
    {
    scanf("%lld%lld",&N,&k);
    matrix bs;
    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
            scanf("%d",&bs.a[i][j]);
    matrix res=quick_power(bs,k);
    res=res%p;
    res.print();
    return 0;
    }

[模板]快速幂,矩阵快速幂

标签:pre   自乘   int   names   blog   power   set   pow   org   

原文地址:https://www.cnblogs.com/nishikino-curtis/p/8494319.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!