快速取模

typedef long long LL;

LL quick(LL a,LL b,LL m)   //a^b%m  快速取模 使得复杂度从0(b)
{                                   //             降低为0(log2(b))
    LL ans=1;
    while(b)
    {
        if(b&1) ans=ans*a%m;
        b>>=1;
        a=a*a%m;
    }
    return ans;
}

LL multi(LL a,LL b,LL m)         //   a*b%m  快速取模
{
    LL ans=0;
    while(b)
    {
        if(b&1) ans=(ans+a)%m;
        b>>=1;
        a=(a+a)%m;
    }
    return ans;
}

例题:

Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63).

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;

LL multi(LL a ,LL b,LL m)
{
    a%=m;
    LL ans=0;
    while(b)
    {
        if(b&1)
        //ans=(ans+a)%m;
        {
            ans+=a;
            if(ans>=m)
            ans-=m;
        }
        b>>=1;


        //a=(a+a)%m;   使用加减及位运算速度比乘除及模运算快
        a<<=1;
        if(a>=m)
        a-=m;
    }
    return ans;
}

LL quick(LL a,LL b,LL m)
{
    LL ans=1;
    a=a%m;
    while(b)
    {
        if(b&1)
        //ans=ans*a%m;
        ans=multi(ans,a,m);
        b>>=1;
        a=multi(a,a,m);
    }
    return ans;
}

int main()
{
    LL a,b,c;
    while(scanf("%I64d%I64d%I64d",&a,&b,&c)!=EOF)                    //有些oj不认识%lld,可以使用%I64d
    {
        printf("%I64d\n",quick(a,b,c));
    }
    return 0;
}

posted @ 2015-08-03 10:48  茶飘香~  阅读(1016)  评论(0编辑  收藏  举报