快速幂取模和快速取模

基本概念及思想
对形如a^b mod m 的运算(b一般较大)
但a,b,m都在long型范围内
算法的主要思想是分治,分而治之。将大的问题分成若干个相似的较小的问题!
具体实现是用递归的方法!
举例
2^100 mod 3
像这种运算如果先算出2^100 的值,然后再模上3,相信比较困难!
我们可以将100变小点
2^100=(2^50)^2 =((2^25)^2)^2=((((2^1)^2)^2)…)^2
若我们已经得出2^50 mod 3的值,我们便很简单地得出2^100 mod 3的值。
按照上述的方法继续分下去…
最终肯定会得到 2^1 mod 3 这种情况!这样就好办了!这便是递归的边界,到此我们就可以返回2 mod 3的值了!
另一个问题,再分时有两种情况!
2^100=(2^50)^2        , 100是偶数
2^99=(2^49)^2*2   , 99是奇数
第二种情况需要在第一种情况上乘上一次基数。
long mod(long a,long b,long m)
{   
    if(!b) return 1;                //边界处理
    if(b==1) return a%m;     //边界处理
    long ans=mod(a,b>>=1,m); //进入下一层
    ans=ans*ans%m;     //返回值ans代表a^(b/2)
    if(b&1) ans=ans*a%m; //奇数情况处理
    return ans;             //返回ans代表a^b mod m
}



快速幂

int pow(int a ,int k)
{
    int rec = 1;
    while( k )
    {
        if (k & 1)
            rec *= a;
        a *= a;
        k >>= 1;
    }
    return rec;
}



  & 表示的是k这一位是否为一即判断是否为奇数,K>>= 表示K的位置右移以为,while(K)是直到K移到最后一位的时候弹出.
举个例子,3^13;13=1*2^3+1*2^2+0*2^1+1*2^0;那么第一次K=13;这个时候K&1表示探查2^0的这一位是否为1;为1,则进行rec*=a; k>>=1表示将13右移一位,即13/2;可以在之前的13的上面直接表示出来.6=1*2^2+1*2^1+0*2^0;这个时候,k&1则为0了。因为2^0的系数是0;

快速幂取模

int ModPow(int a,int b,int n) 
{ 
    int rec=1; 
    while(b) 
    { 
        if (b & 1) 
            rec = (rec * a) % n; 
        a = (a * a) % n; 
        b >>= 1; 
    } 
    return rec % n; 
} 


模运算规则:
模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a + b) % p = (a % p + b % p) % p
(a – b) % p = (a % p – b % p) % p
(a * b) % p = (a % p * b % p) % p
ab % p = ((a % p)b) % p
结合率:
((a+b) % p + c) % p = (a + (b+c) % p) % p
((a*b) % p * c)% p = (a * (b*c) % p) % p


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值