快速幂
原理
求(a^b)。
例如,(b=11)时,其二进制为(1011),又有(11=2^3 imes 1+2^2 imes 0+2^1 imes 1+2^0 imes 1)
所以
[a^{11}=a^{2^3+2^1+2^0}
]
从而
[a^{11}=a^{2^3} imes a^{2^1} imes 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;
}