快速幂
快速幂原理:就是把指数转化成二进制,并进行分解。
(参考资料:https://www.cnblogs.com/CXCXCXC/p/4641812.html)
举例:
算法原理其实和所想的那样大同小异,都是利用a的n次方等于n个a相乘。
int poww(int a, int b) {
int ans = 1, base = a;
while (b) {
if (b & 1)
ans *= base;
base *= base;
b >>= 1;
}
return ans;
}
其实想一想,每次操作是移除掉二进制数的最后一位(b>>=1),然后每一位的2是指数递增,所以base*base每一次操作都得有(第一次是,第二次就是
,而第三次就是
,奇妙),然而,答案并不是所有的base*base都需要,当然只有二进制位上是1的那里才需要(也就是&1操作的意义)。所以从最后一个式子可以看出来,a的指数操作是每一轮都要进行,而点乘操作在if条件满足情况下才进行。
矩阵快速幂
和快速幂意义,只不过,乘法变成了矩阵乘法。
手写一个的矩阵乘法就可以!
(参考资料:https://blog.youkuaiyun.com/wust_zzwh/article/details/52058209)
const int N=10;
int tmp[N][N];
void multi(int a[][N],int b[][N],int n)
{
memset(tmp,0,sizeof tmp);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
tmp[i][j]+=a[i][k]*b[k][j];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]=tmp[i][j];
}
int res[N][N];
void Pow(int a[][N],int n)
{
memset(res,0,sizeof res);//n是幂,N是矩阵大小
for(int i=0;i<N;i++) res[i][i]=1;
while(n)
{
if(n&1)
multi(res,a,N);//res=res*a;复制直接在multi里面实现了;
multi(a,a,N);//a=a*a
n>>=1;
}
}