快速幂

快速幂(取模)

  • 快速幂
    • 矩阵快速幂

首先我们说一下取模规则:
(ab)%c=((a%c)(b%c))%c
(a±b)%c=((a%c)±(b%c))%c
:千万千万不要漏掉了最外面的取余,漏掉就错了!!!

快速幂

对于an来说;如果n较小,我们可以直接计算,时间复杂度为O(n),而如果n过大,可能在某些题中就会有超时的风险,所以我们有了快速幂来帮我们优化时间。
大致思路为:
1.将n转换为二进制数相加:如n=7,7的二进制为111,则7=22+ 21 + 20,所以a7=a^ 22 +a^ 21 + a^ 20 ;

2.an = a^(n0+n1* 21+n2 * 22+……+nn * 2n)
an=a^n0 * a^(n1 * 21) * a^(n2 * 22) …… a^(nn * 2n)

3.n为偶数时,an=(a2)^(n/2)
n为奇数:an=a * (a2)^((n-1)/2)

typedef long long ll;
ll quickpow(ll a, ll n, ll mod)//a为底,n为指,mod为模
{
	ll ans=1;
	a=a%mod;
	while(n>0) 
	{
		if(n&1)//当n为奇数时		
			ans=(ans*a)%mod;//乘上剩下的一个n
		n>>=1;//进行二进制位移
		a=(a*a)%mod;//将a平方,更新a
	}
	return ans;
}

矩阵快速幂

矩阵快速幂可以求解常系数齐次线性递推式
类似于:f(n)=f(n-1)+f(n-2)+n+c;(c为常数)
方程有多少项,矩阵就有多少列;
典型:Fibonacci 数列(典型模板):
[F n+1 F n F n F n−1 ]\begin{bmatrix} F~n+1~ & F~n~ \\ F~n~ & F~n-1~ \\ \end{bmatrix}[F n+1 F n F n F n1 ]=[1110]\begin{bmatrix} 1 & 1 \\ 1 & 0 \\ \end{bmatrix}[1110]n

其中[1110]\begin{bmatrix} 1 & 1 \\ 1 & 0 \\ \end{bmatrix}[1110]n这个矩阵可以由[F n+1 F n ]\begin{bmatrix} F~n+1~ & F~n~ \\ \\ \end{bmatrix}[F n+1 F n ]*[xyzw]\begin{bmatrix} x & y \\ z & w \\ \end{bmatrix}[xzyw]=[F n F n−1 ]\begin{bmatrix} F~n~ & F~n-1~ \\ \\ \end{bmatrix}[F n F n1 ]求出
矩阵快速幂的函数和快速幂的函数基本一致,就是数的幂变成了矩阵的,也就是底数变成了矩阵,所以要涉及到矩阵的乘法,如:
(1234)\begin{pmatrix} 1 & 2 \\ 3 & 4 \\ \end{pmatrix}(1324) * (1234)\begin{pmatrix} 1 & 2 \\ 3 & 4 \\ \end{pmatrix}(1324) = (1∗1+2∗31∗2+2∗43∗1+4∗33∗2+4∗4)\begin{pmatrix} 1*1+2*3 & 1*2+2*4 \\ 3*1+4*3 & 3*2+4*4 \\ \end{pmatrix}(11+2331+4312+2432+44)
详细内容会在线性代数中学到
矩阵乘法

void mu(ll a[maxn][maxn],ll b[maxn][maxn])
{
    memest(c,0,sizeof(c));
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	for(int k=1;k<=n;k++)
	{
		c[i][j]=(c[i][j]+a[i][k]*b[k][j]%mod)%mod;//注意取模
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		b[i][j]=c[i][j];
}

[1110]\begin{bmatrix} 1 &amp; 1 \\ 1 &amp; 0 \\ \end{bmatrix}[1110]相当于代码中的a矩阵

快速幂

void qup(ll n)
{
	while(n>0)
	{
		if(n&1)
		{
			mu(a,b);//a,b为两个矩阵,可在主函数或这个函数中对他们进行初始化
		}
		mu(a,a);
		n>>=1;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值