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