题目链接
首先介绍两个定理。
整数唯一分解定理:任意正整数都有且只有一种方式写出素数因子的乘积表达式。
\(A=(p1k1 p2k2 ...... pnkn \)
求这些因子的代码如下
for(int i=2;i*i<=a;++i){
if(!(a%i)){
prime[++num]=i;
while(!(a%i)){
a/=i;
sum[num]++;
}
}
}
if(a!=1){
prime[++num]=a;
sum[num]=1;
}
唯一分解定理
约数和公式:对于已经分解的整数A,有A的所有因子和为
\( S= (1+p1+p12+p13+......+p1k1) (1+p2+p22+p23+......+p2k2)........(1+pn+pn2+pn3+......+pnkn) \)
所以局势明朗。用快速幂求出p的k*b次方,然后递归求和。代码如下
long long Sum(long long p,long long n){
if(n==0) return 1;
if(n&1) return (Sum(p,n>>1)*(1+Pow(p,(n>>1)+1)))%mod;
return (Sum(p,(n>>1)-1)*(1+Pow(p,(n>>1)+1))+Pow(p,n>>1))%mod;
}
解题代码如下
#include<cstdio>
#include<cctype>
#define mod 9901
inline long long read(){
long long num=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch)){
num=num*10+ch-'0';
ch=getchar();
}
return num*f;
}
int prime[10000];
int sum[10000];
int num;
long long Pow(long long n,long long i){
if(i==0) return 1;
if(i==1) return n%mod;
long long ret=Pow(n,i>>1);
if(i&1) return (((ret*ret)%mod)*n)%mod;
return (ret*ret)%mod;
}
long long Sum(long long p,long long n){
if(n==0) return 1;
if(n&1) return (Sum(p,n>>1)*(1+Pow(p,(n>>1)+1)))%mod;
return (Sum(p,(n>>1)-1)*(1+Pow(p,(n>>1)+1))+Pow(p,n>>1))%mod;
}
int main(){
long long a=read(),b=read();
for(int i=2;i*i<=a;++i){
if(!(a%i)){
prime[++num]=i;
while(!(a%i)){
a/=i;
sum[num]++;
}
}
}
if(a!=1){
prime[++num]=a;
sum[num]=1;
}
int ans=1;
for(int i=1;i<=num;++i)
ans=(ans*Sum(prime[i],sum[i]*b)%mod)%mod;
printf("%d",ans);
return 0;
}
转载于:https://www.cnblogs.com/cellular-automaton/p/7483285.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)