快速幂 & 矩阵快速幂

快速幂

实数快速幂

普通求幂的方法为 O(n) 。在一些要求比较严格的题目上很有可能会超时。所以下面来介绍一下快速幂。

快速幂的思想其实是将数分解,即ab可以分解为(a2)*(a2)...a;然后再分别算a2;这样的计算量由O(n)一下变成 \(O(logn)\)

模板代码如下:

ll pow(int a,int b)
{
    if(b==0)    return 1;
    ll res=1 % mod;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1; 
    }
    return res;
}

当然,如果题目没要求取模操作的话,可以将%mod删掉即可。

矩阵快速幂

矩阵快速幂其实就是将矩阵乘法和快速幂结合起来, 再用一下单位矩阵的性质即可。复杂度\(O(log{k} * n*m )\),下面是实现代码:

LL n, k;
struct node{
    LL arr[maxn][maxn];
}a;
node mul(node a, node b)
{
    node ans;
    memset(ans.arr, 0, sizeof(ans.arr));
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= n; ++j){
            for(int k = 1; k <= n; ++k){
                ans.arr[i][j] = (ans.arr[i][j] + a.arr[i][k] * b.arr[k][j]) % mod;
            }
        }
    }
    return ans;
}
node operator ^(node a, LL k)
{
    node ans;
    memset(ans.arr, 0, sizeof(ans.arr));
    for(int i = 1; i <= n; ++i) ans.arr[i][i] = 1;
    while(k){
        if(k & 1)   ans = mul(ans, a);
        a = mul(a, a);
        k >>= 1;
    }
    return ans;
}

node ans = a ^ k;
输出ans即可...
posted @ 2020-02-02 15:34  StungYep  阅读(116)  评论(0编辑  收藏  举报