快速幂+乘模 模板

/**************
快速幂模板
调用:Quk_Mul(a,b,mod)
返回:a^b%mod
复杂度:当mod>10^9,log(mod)*log(b),否则log(b)
***************/
long long Mod_Mul(long long a,long long b,long long mod)
{
    long long msum=0;
    while(b)
    {
        if(b&1) msum = (msum+a)%mod;
        b>>=1;
        a = (a+a)%mod;
    }
    return msum;
}

long long Quk_Mul(long long a,long long b,long long mod)
{
    bool qmflag=mod>2e9?1:0;
    long long qsum=1;
    while(b)
    {
        if(b&1) qsum = (qmflag==1) ? Mod_Mul(qsum,a,mod) : (qsum*a)%mod;
        b>>=1;
        a = (qmflag==1) ? Mod_Mul(a,a,mod) : (a*a)%mod;
    }
    return qsum;
}

 

/*****-矩阵快速幂模板-*****/
//复杂度O(N^3)
//构造好xx,然后返回rt = xx^n
#define MN 2
void calmul(long long s[MN][MN],long long t[MN][MN])
{
    long long tmp[MN][MN];
    memset(tmp,0,sizeof(tmp));
    for(int k=0;k<MN;k++)
        for(int i=0;i<MN;i++)
            for(int j=0;j<MN;j++)
            {
                tmp[i][j]=(tmp[i][j]+s[i][k]*t[k][j])%MOD;
            }
    for(int i=0;i<MN;i++)
        for(int j=0;j<MN;j++)
            s[i][j]=tmp[i][j];
}

void Quk_Mul(long long rt[MN][MN],long long xx[MN][MN],long long _n)
{
    long long _tmp[MN][MN],_sum[MN][MN];//为了不改变传入的xx
    for(int i=0;i<MN;i++)
        for(int j=0;j<MN;j++) _tmp[i][j] = xx[i][j],_sum[i][j]=0;
    for(int i=0;i<MN;i++) _sum[i][i] = 1;
    while(_n)
    {
        if(_n&1) calmul(_sum,_tmp);
        _n >>= 1;
        calmul(_tmp,_tmp);
    }
    for(int i=0;i<MN;i++)
        for(int j=0;j<MN;j++) rt[i][j] = _sum[i][j];
}

 

posted @ 2015-12-20 11:42  chenhuan001  阅读(200)  评论(0编辑  收藏  举报