1.什么是倍增思想?
在求类似幂运算或者某些乘法的过程中,有时需要大量的循环,这样时间复杂度度便会过高,此时就会很浪费时间,那么有什么方法可以避免此类问题呢?这时候就可以将某数倍增,例如:对a频繁的“*=”自身,达到倍增的效果。
2.倍增思想解决题目时遇到的问题?
2.1.该类题目经常会求某数对另一个数取模,但问题就是在求解过程中数据很容易超过long long的范围,此时我们可以在求解过程中不断的对计算过程中的数取模,这得益于取模运算具有分配律。
2.2.同时在倍增过程中,频繁对a“*=”自身,只能产生a的二的整数次幂,但b不一定就是a的二的整数次幂,此时我们可以对b的二进制位进行操作,如果b的某二进制位是1,则对最终结果乘上a的该位的对应的权值次方,如果是0,则不做处理。
3.举几个例子说明倍增思想如何应用
例一:
这道题目a,b数据范围为2^18,如果贸然的循环b次很容易超时,此时我们就可以采用倍增思想来解决,省略输入输出过程,代码如下:
typedef long long LL;
LL qpow(LL a,LL b,LL p);
{
LL ret = 1;
while(b)
{
if(b&1) ret = (ret * a) % p;
a = (a * a) % p;
b >>= 1;
}
}
return ret;
}
例二:
该题与上一题类似,只是乘法变成了加法,直接上代码:
typedef long long LL;
LL qsum(LL a,LL b,LL p)
{
LL sum = 0;
while(b)
{
if(b&1) sum = (sum + a) % p;
a = (a + a) % p;
b >>= 1;
}
return sum;
}
结语:
这就是倍增思想的全部内容了,欢迎各位于晏、亦菲和我一起交流学习!