快速幂&矩阵快速幂


快速幂

原理

\(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;
}
posted @ 2020-04-29 18:07  StreamAzure  阅读(140)  评论(0编辑  收藏  举报