数学---快速幂

本文章内容大多采集罗老师著作:《算法竞赛入门到进阶》 清华大学出版社, 感谢罗老师的支持。

1. 快速幂概念:

  1. 快速幂以及扩展的矩阵快速幂,由于场景比较

  2. 常见,因此竞赛常出现。
    问题:高效的计算an次幂,这里n很大

    分析:假如a=10,n=9,这样的情况就连自带高精度的Java也无法处理,一是数字太大,二是计算时间很长。
    使用快速幂解法1:先算a²,之后再算(a²)²,巧妙的使用了分治法,时间复杂度为O(㏒₂n) 上代码:

	int fastPow(int a,int n){
		if(n==1) return a;
		int temp=fastPow(a,n/2);//分治方法---这里a在增大,n在减小
		if(n%2==1)	//奇数个a,这里可以写为  if(n&1)
			return temp*temp*a;
		else 
			return temp*temp;
} 

方法2:位运算快速幂

  1. 假如求a¹¹,可以分解成(a²)³、a²、a¹,其幂数分别为:8、2、1,
    使用二进制表示它们的和,为1011;其中的0是不存在幂数的,因此要跳过0。这里做个判断即可,1011中的0就是需要跳过的。这个判断,利用二进制运算很容易实现:
    (1)n&1,取n的最后一位,并判断这一位是否需要跳过。
    (2)n>>1,把n向右移动一位,目的是把刚才处理过的n最后一位去掉。 代码:
	int fastPow(int a,int n){
		int base=a;//不定义base,直接用a进行计算也可以
		int res=1;//用res返回结果
		while(n){
			if(n&1)//如果n的最后一位是1,表示这个地方需要乘
				res*=base;
			base*=base;//推算乘积,a²->(a²)²->、、、、
			n>>1;//n右移一位,把刚处理过的n的最后一位去掉
	}
	return res;
}

2. 快速幂取模

  1. 存在意义:
    由于幂运算结果非常大,常常会超出变量类型的最大值,甚至超出内存所能存放的最大数,所以涉及快速幂的题目,通常都要做取模操作,缩小结果。
    根据模运算的性质,在快速幂中做取模操作,对aⁿ 取模,和先对a取模,和先对a取模在做模运算的结果是一样的,即:
    aⁿ mod m=(a mod m)ⁿ mod m
    下面修改位运算pastPow()函数,加上取模操作。以一个残缺程序实验:
	if(n&1)
		res = (base*res)%mod;
	base =(base*base)%mod;

3. 矩阵快速幂:

  1. 给定一个m×m 的矩阵A,求它的n次幂Aⁿ
    ,这也是常见的计算。同样有矩阵快算幂的算法,原理是把矩阵当作变量来操作,程序和上面的很相似。
    首先需要定义矩阵的结构体,并定义矩阵相乘的操作。注意矩阵相乘也需要取模。
    代码:
	const int MAXN = 2;//根据题目要求定义矩阵的阶,本例中是2
	const int MOD = 1e4;//根据题目要求定义模
	struct Matrix{
		int m[MAXN][MAXN];
		Matrix(){
			memset(m,0,sizeof(m));//第一个参数是赋值位置,第二个参数是要赋的值,第三个参数是赋值的个数
	}		
};
	Matrix Multi(Matrix a,Matrix b){  //矩阵的乘法
		Matrix res;
		for(int i=0;i<MAXN;i++)
			for(int j=0;j<MAXN;j++)
				for(int k=0;k<MAXN;k++)
					res.m[i][j]=(res.m[i][j] + a.m[i][k] * b.m[k][j])%MOD;
		return res;
	}	 
   下面是矩阵快速幂的程序代码,和前面单变量的快速幂的
   代码非常相似
Matrix fastm(Matrix a,int n){
	Matrix res;
	for(int i=0;i<MANX;i++)
		//初始化为单位矩阵,相当于前面程序中的“int res = 1;”
		res.m[i][i];
	while(n){
		if(n&1)
			res = Multi(res,a);
		a = Multi(a,a);
		n>>=1;
		}
		return res;
	}
  1. 矩阵快速幂的复杂度:上面求Aⁿ,A是m×m的方阵,其中矩阵乘法的复杂度是O(㏒₂n),合起来是O(m³*㏒₂n)。
    应用矩阵快速幂的难点在于如何把地推关系转化为矩阵。

猜你喜欢

转载自blog.csdn.net/qq_46144237/article/details/107640673
今日推荐