广义快速幂

设:○为一种运算且与集合V构成群,a∈V,e为○运算的幺元。

即e满足对于任意的a,有 e○a=a○e=a

我们可以记

a0=e

an=an-1○a

则有以下性质

an+m=an○am

则此时计算a关于○运算的n次幂的快速幂可以这样写

res=e;temp=a;

while(n)

{

        if(n&1)

                res=res○temp;

        temp=temp○temp;

        n>>=1;

}

return res;

其中 加法幺元为 0 ,乘法 为 1

  因为 n+0 不变, n*1 不变

 

加法幂运算

ll quick_mul(ll a, ll b, ll c)    
{
	ll res = 0;
	while (b != 0)
	{
		if (b % 2 == 1)
			res = (a + res) % c;
		a = (a + a) % c;
		b /= 2;
	}
	return res;
}

乘法幂运算

ll quick_pow(ll a, ll b, ll c)
{
    ll res = 1;
    while (b != 0)
    {
        if (b % 2 == 1)
            res=(res*a)%c    //优化   res = quick_mul(res, a, c);
        a = cq(a, a, c);
        b /= 2;
    }
    return res;
}

 

首先,要知道 (a*b)%c==(a%c)*(b%c)  (a+b)%c==a%c+b%c

  具体可以理解为  先把 取余c     看成不断减c,直至不够减

  (a*b)%c==( ((a%c)*(c*x))  *  ((b%c)(c*y))  )%c               a+b)%c==( (a%c+a*x) +( b%c+b*y) )%c

  其中  ((a%c)*(c*x)) 表示 a, x表示无关结果的未知数  ,所以 (c*x) 就给减没了   同理可证

         

对于 a的b次方

若 b为 奇数    则 a的b次方 == a的b/2次方  *  a的b/2次方  * a

若 b为 偶数    则 a的b次方 == a的b/2次方  *  a的b/2次方  

所以代码如上

 

另外还有一点   就是乘法幂运算 可以运用 加法幂运算 进行优化

你可能感兴趣的:(广义快速幂)