题目:传送门
题目大意:输入两个数 A,B 求 AB 的所有因子之和。
分析:
这道题折腾了很久啊,值得写一写报告。
首先一个大于
1
的正整数
X=pe11∗pe22∗...∗penn,其中pn为素数。
那么 X 的所有因子之和为:
所以我们先求 A 的素因子分解,然后答案就是:
求多项式 (1+x1+x2+...+xn)%mod 有两种方法:
1)递归二分:
当 n 为奇数时,
当 n 为偶数时,
2)等比通项:
显然
sum%mod=xn+1−1x−1%mod
形如
ab%mod
的分式取模也有两种方法,一种是求分母
b
在模ps:在一篇题解中,大神给出了求
1→p(p为奇素数)
模
p
的所有逆元的一个递推式,用这个递推式就可以在
代码:
/*等比通项*/
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
typedef long long LL;
LL a,b;
LL p,e;
LL m=9901;
LL multi(LL a,LL b,LL mod){
LL res=0;
a%=mod;
b%=mod;
while(b){
if(b&1) res=(res+a)%mod;
a=(a*2)%mod;
b>>=1;
}
return res;
}
LL power(LL a,LL b,LL mod){
LL res=1;
a%=mod;
while(b){
if(b&1) res=multi(res,a,mod);
a=multi(a,a,mod);
b>>=1;
}
return res;
}
LL sum(LL p,LL n, mod){
if(!n) return 1;
else{
if(n&1) return sum(p,n/2)*(power(p,n/2+1,mod)+1)%mod;
else return sum(p,n/2-1)*(power(p,n/2+1,mod)+1)*power(p,n/2,mod)%mod;
}
}
void solve(){
LL ans=1;
for(int i=2;i*i<=a;){
if(a%i==0){
p=i;
e=0;
while(!(a%i)){
e++;
a/=i;
}
if((p-1)%m==0){
LL M=m*(p-1);
ans=ans*(power(p,e*b+1,M)+M-1)%M/(p-1)%m;
}
else ans=ans*(power(p,e*b+1,m)-1)*power(p-1,m-2,m)%m;
}
if(i==2) i++;
else i+=2;
}
if(a>1){
p=a; e=1;
if((p-1)%m==0){
LL M=m*(p-1);
ans*=(power(p,e*b+1,M)+M-1)%M/(p-1)%m;
}
else ans=ans*(power(p,e*b+1,m)-1)*power(p-1,m-2,m)%m;
}
cout<<(ans+m)%m<<endl;
}
int main(){
while(cin>>a>>b){
solve();
}
return 0;
}
/*递归二分*/
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
typedef long long LL;
LL a,b;
LL p,e;
LL mod=9901;
LL power(LL a,LL b){
LL res=1;
a%=mod;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
LL sum(LL p,LL n){
if(!n) return 1;
else{
if(n&1) return sum(p,n/2)*(power(p,n/2+1)+1)%mod;
else return (sum(p,n/2-1)*(power(p,n/2+1)+1)+power(p,n/2))%mod;
}
}
void solve(){
LL ans=1;
for(int i=2;i*i<=a;){
if(a%i==0){
p=i;
e=0;
while(!(a%i)){
e++;
a/=i;
}
ans=ans*sum(p,e*b)%mod;
}
if(i==2) i++;
else i+=2;
}
if(a>1){
p=a; e=1;
ans=ans*sum(p,e*b)%mod;
}
cout<<(ans+mod)%mod<<endl;
}
int main(){
while(cin>>a>>b){
solve();
}
return 0;
}