lightoj 1054 - Efficient Pseudo Code 求所有n^m的所有因子和

来源:互联网 发布:php观察者模式适用于哪 编辑:程序博客网 时间:2024/04/28 10:14

题意:求n^m的所有因子和。

题解:我们需要先知道,一个数X=p1^t1*p2^t2*...*pk^tk(pi为素数),还需要知道X的所有因子和sum(X)=(p1^0+p1^1+...+p1^t1)*...*(pk^0+pk^1+...+pk^tk)。证明略,以前证明过,可以自己在我其他文中找下,好像那题跟这题一样,就是因子都是排列组合ti得到的。所以结果就很简单了,n^m=p1^(t1*m)*...pk^(tk^m);还需要筛选下素数,和快速幂以及等比数列求和,还有除法取余(这个就是逆元和费马定理:a/b%mod=a*b^(mod-2)%mod)。




#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>using namespace std;#define LL long longconst int mod=1e9+7;const int maxn=1e5+10;LL prime[maxn],vis[maxn],t;void init(){    LL i,j,k,m;    t=0;    m=(LL)sqrt(maxn+0.5);    memset(vis,0,sizeof(vis));    for(i=2;i<=m;i++)    {        if(!vis[i])        for(j=i*i;j<maxn;j+=i)        vis[j]=1;    }    for(i=2;i<maxn;i++)    if(!vis[i])prime[t++]=i;}LL pow_mod(LL a,LL b){    LL s=1;    while(b)    {        if(b&1)s=(s*a)%mod;        a=(a*a)%mod;        b=b>>1;    }    return s;}LL find(LL a,LL b){    LL ans;    ans=pow_mod(a,b)-1;    ans=ans*pow_mod(a-1,mod-2)%mod;    ans=(ans+mod)%mod;    return ans;}int main(){    init();    LL n,m,T,tt=0;    scanf("%lld",&T);    while(T--)    {        scanf("%lld%lld",&n,&m);        LL i,j,k,num;        LL ans=1;        for(i=0;i<t&&prime[i]*prime[i]<=n;i++)        {            if(n%prime[i]==0)            {                num=0;                while(n%prime[i]==0){n=n/prime[i];num++;}                //cout<<find(prime[i],m*num+1)<<endl;                ans=ans*find(prime[i],m*num+1)%mod;            }        }        if(n>1)        ans=ans*find(n,m+1)%mod;        printf("Case %lld: %lld\n",++tt,ans);    }    return 0;}


原创粉丝点击