快速幂&矩阵快速幂
快速幂
原理
求\(a^b\)。
例如,\(b=11\)时,其二进制为\(1011\),又有\(11=2^3\times 1+2^2 \times 0+2^1 \times 1+2^0 \times 1\)
所以
\[a^{11}=a^{2^3+2^1+2^0}
\]
从而
\[a^{11}=a^{2^3} \times a^{2^1} \times a^{2^0}
\]
代码
long long quickpower(long long x,long long y)
{
long long ans=1,cnt=x;
while(y)
{
if(y&1) ans*=cnt;
//判断y的二进制数的末位是否为0,若为0则舍弃(0作乘数结果仍为0)
cnt*=cnt;
y>>=1;
//右移一位,相当于除以2
}
return ans;
}
最初\(ans=1,cnt=a,y=1011\)
\(1011\&1\)为真,\(a^1\)这一位要算入,乘入\(ans\)。然后\(a\)自乘变为\(a^2\),\(y\)右移一位
\(101\&1\)为真,\(a^2\)这一位要算入,乘入\(ans\)。然后\(a\)自乘变为\(a^ 4\),\(y\)右移一位
\(10\&1\)为假,不算。然后\(a\)自乘变为\(a^8\),\(y\)右移一位
\(1\&1\)为真,\(a^ 8\)这一位要算入,乘入\(ans\)。然后\(a\)自乘变为\(a^{16}\),\(y\)右移一位
\(y\)为\(0\),跳出循环
矩阵快速幂
定义矩阵
struct node {
int mat[15][15];
}x,y;
定义矩阵乘法
node mul(node x,node y){
node tmp;
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
tmp.mat [i][j]=0;
for(int k=0;k<len;k++) tmp.mat [i][j] += x.mat [i][k] * y.mat[k][j];
//x,y是相同的k阶方阵
}
}
return tmp;
}
也可以将二者合并,在结构体中重载运算符
struct matrix{
ll a1,a2,b1,b2;
matrix operator*(const matrix &y)//重载乘号运算符
{
matrix ans((a1 * y.a1 + a2 * y.b1),
(a1 * y.a2 + a2 * y.b2),
(b1 * y.a1 + b2 * y.b1),
(b1 * y.a2 + b2 * y.b2));
return ans;
}
};
矩阵快速幂
node matpow(node x,int num){
//num为幂
node ans(1, 0, 0, 1);//单位矩阵
while(num){
if(num&1){
ans=mul(ans,x);
}
x=mul(x,x);
num=num>>1;
}
return ans;
}