约数和公式
对于已经分解的整数A=(p1^k1)(p2^k2)(p3^k3)….(pn^kn)
有A的所有因子之和为
S = (1+p1+p1^2+p1^3+…p1^k1) * (1+p2+p2^2+p2^3+….p2^k2) * (1+p3+ p3^3+…+ p3^k3) * …. * (1+pn+pn^2+pn^3+…pn^kn)
代码
由于取模数只有9901,如果素因子刚好是9901*x+1,那么就无法求出逆元,因此用二分求等比数列的和
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
#include <queue>
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=a;i<b;i++)
const int INF=0x3f3f3f3f;
const int maxn=1e4+50;
const int mod=9901;
#define pii pair<int,int>
#define mp(a,b) make_pair(a,b)
typedef long long ll;
typedef unsigned int ui;
using namespace std;
bool notPrime[maxn];
int prime[maxn];
int cnt;
void initPrime(){
mem(notPrime,0);
cnt=0;
for(int i=2;i<maxn;i++){
if(notPrime[i]) continue;
prime[cnt++]=i;
for(int j=2*i;j<maxn;j+=i)
notPrime[j]=true;
}
notPrime[0]=notPrime[1]=1;
}
map<ll,ll> ma;
map<ll,ll>::iterator it;
void getFac(int n){
for(int i=0;i<cnt;i++){
int p=prime[i];
if(p>n) break;
while(n%p==0){
ma[p]++;
n/=p;
}
}
if(n!=1) ma[n]++;
}
ll qPow(ll x,ll n){
ll ret=1;
while(n){
if(n&1) ret=ret*x%mod;
x=x*x%mod;
n>>=1;
}
return ret;
}
ll sum(ll p,ll n){//计算1+p+p^2+````+p^n
if(p==0)return 0;
if(n==0)return 1;
if(n&1){
return ((1+qPow(p,n/2+1))%mod*sum(p,n/2)%mod)%mod;
}
else return ((1+qPow(p,n/2+1))%mod*sum(p,n/2-1)+qPow(p,n/2)%mod)%mod;
}
int main()
{
#ifndef ONLINE_JUDGE
//freopen("in.txt","r",stdin);
//freopen("d:\\out.txt","w",stdout);
#endif
initPrime();
int a,b;
while(~scanf("%d %d",&a,&b)){
ma.clear();
if(a==0){
puts("1");
continue;
}
getFac(a);
ll ans=1;
for(it=ma.begin();it!=ma.end();it++){
it->second*=b;
//cout<<it->first<<" "<<it->second<<endl;
ll q=it->first,mi=it->second;
ans=(ans*sum(q,mi))%mod;
}
printf("%lld\n",ans);
}
return 0;
}