题意:求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 long
const 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;
}