数论之————快速幂+矩阵快速幂

本文介绍了快速幂算法,解释了为何使用快速幂来高效计算大数次方,并提供了代码模板。接着,文章深入讨论了矩阵快速幂,阐述了矩阵乘法规则,并指出其通常与斐波那契数列问题结合使用。最后,提到了单位矩阵的概念及其性质,并给出了相关代码示例。

快速幂,顾名思义快速求一个数的次方。
为什么要用快速幂呢?
因为一般方法会超时,当次方很大的时候。
皮一下23333
——————————————————————————————————————————————

正文开始

当n=2k,那么xn=((x2)2)…
只要做k次平方运算就好了,现将n表示为2的幂次的和
得到 n=2k1+2k2+2k3+…
所以 xn=x^ 2k1*x^ 2k2······ ——————理解为(x的2的k1次方)
在依次求x^ 2k的同时计算,最终得到了O(log n)的快速幂计算方法。
比如 x22=x16*x4*x2; (22的二进制为10110)得到了22是那些2的次方和得到的。

因为算的数一般都比较大,所以基本题目都要求有取余操作。
代码模板:
typedef long long LL;
LL mod_pow(LL x,LL n,int mod)
{
    LL res=1;
    while(n>0)
    {
        if(n&1) res=res*x%mod;      //如果二进制最低位是1,则乘上x^(2^i)
        x=x*x%mod;          //平方操作
        n>>=1;               //位操作,10110向右移一位得到1011
    }
    return res;
}

——————————————————————————————————————————————————————

补充:矩阵快速幂

矩阵相乘,线代都学过。在这我再讲一下,矩阵A乘矩阵B
这里写图片描述
得到:
这里写图片描述
矩阵相乘就是第一个矩阵的行乘以第二个矩阵的每列的和。
比如:-1=1 * 1+2 * (-1);
若A为n×k矩阵,B为k×m矩阵,则它们的乘积AB将是一个n×m矩阵。前一个矩阵的列数应该等于后一个矩阵的行数,得出的矩阵行数等于前一个矩阵的行数,列数等于后一个矩阵的行数。可以根据上边的例子验证一下。
定义矩阵肯定要用二维数组,如果需要定义多个那么我们可以用结构体来实现。

话不多少上代码(实现矩阵乘法):
const int mod=1e4;
struct mat
{
    LL a[2][2];
};
mat tc(mat x,mat y)
{
    mat res;
    memset(res.a,0,sizeof(res.a));
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        for(int k=0;k<2;k++)
    {
        res.a[i][j]+=x.a[i][k]*y.a[k][j];
        res.a[i][j]%=mod;
    }
    return res;
}
但是多数情况矩阵乘法会和斐波那契数列联系在一起。

f[n] = 1f[n-1]+1f[n-2]
f[n-1] = 1f[n-1] + 0f[n-2];
可以得到:
这里写图片描述
可以推出:
这里写图片描述

在讲一下单位矩阵:

n*n的矩阵对角线都为1,任何矩阵乘单位矩阵都是自己本身。
如下就是一个单位矩阵:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
大家都知道斐波那契一般给的n都很大,用一般方法求肯定超时。所以引入矩阵快速幂。快速幂我上边讲过,很好理解,矩阵快速幂就是把数的幂换成矩阵的幂。

上代码:

LL mod_pow()
{
    mat res,c;
    c.a[0][0]=1; c.a[0][1]=1;
    c.a[1][0]=1; c.a[1][1]=0;
    memset(res.a,0,sizeof(res.a));
    for(int i=0;i<2;i++)
        res.a[i][i]=1;    //构造单位矩阵
    while(n>0)
    {
        if(n&1) res=tc(res,c);   //tc是矩阵乘法
        c=tc(c,c);    //c矩阵就是上边快速幂的x
        n>>=1;
    }
    return res.a[0][1];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值