LightOJ 1054 求n^m%mod

来源:互联网 发布:网络扎金花 编辑:程序博客网 时间:2024/04/30 07:20

任意数n可以写成 n = p1^k1 * p2^k2  * p3^n3 * ....* pn^kn(p1,p2,...pn为质因数)

n^m 的约数 一定是 p1^m1 * p2 ^m2 *p3^m3 *....* *pn^mn (m1<k1*m,m2<k2*m,....mn<kn*m)


所以约数的和为(p1^0+p1^1+.....+p1^(m*k1))*(p2^0+p2^1+...+p2^(m*k2))*......*(pn^0+pn^1+...+pn^(m*kn))

该多项式展后每一项都为一个约数。


对n^m%mod 可以转换为(n^2)^(m/2)%mod * n^(m%2) %mod = (n^2%mod)^m/2%mod * n^(m%2)%mod

对于前n项和求模,可转为前n/2项 * (1+p^n/2),及可通过递归求解


#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;


const int mod = 1000000007;
int prime[70000];
int trueprime[70000];

int count = 0;
long long ans=1;
long long yu = 1;

long long powMod(long long m,long long n)
{
    yu  = 1;
    while(n)
    {
        if(n%2==1)
            yu = (yu*m)%mod;
        m = m*m%mod;
        n/=2;
    }
    return yu;
}


long long sumMod(long long m,long long n)
{
    if(n==0)
        return 1;
    else if(n==1)
    {
        return (m+1)%mod;
    }
    else if(n%2==0)
    {
        return (((powMod(m,n/2)+1)*sumMod(m,n/2-1))%mod + powMod(m,n)%mod)%mod;
    }
    else
    {
        return ((powMod(m,n/2+1)+1)*sumMod(m,n/2))%mod;
    }
}


void make_prime()
{
    for(int i = 2;i<70000;i++)
    {
        if(prime[i]==0)
        {
            if(i < sqrt(70000.0))
            {
                for(int j = i*i;j<70000;j+=i)
                {
                    prime[j] = 1;
                }
            }
            trueprime[count++] = i;
        }
    }
}


void getmi(long long m,long long n)
{
    for(int i = 0;i<count&&prime[i]*prime[i]<=m;i++)
    {
        long long mi = 0;
        while(m%trueprime[i]==0)
        {
            mi++;
            m /= trueprime[i];
        }
        mi*=n;
        if(mi!=0)
            ans = ans*sumMod(trueprime[i],mi)%mod;
    }

    if(m>1)
        ans = ans*sumMod(m,n)%mod;
}


int main()
{
    int m;
    make_prime();
    long long p,q;
    scanf("%d",&m);
    for(int i = 1;i<=m;i++)
    {
        ans = 1;
        scanf("%lld %lld",&p,&q);
        getmi(p,q);
        printf("Case %d: %lld\n",i,ans);
    }
    return 0;
}


原创粉丝点击