题目描述
给出 A 和
B ,求:∑d|ABd
输入描述
两个非负整数 A ,
B
输出描述
仅一个正整数,表示答案
输入样例
2 3
输出样例
15
样例解释
23=8,而8的因子有1,2,4,8,而1+2+4+8=15
数据范围
A,B≤1012
质因数分解
AB
AB=pk11pk22...pknn
则
Sum=(1+p1+p21+...+pk11)(1+p2+p22+...+pk22)...(1+pn+p2n+...+pknn)
等比数列求和公式或分治计算 Sum
O(log2n)
#include <cstdio>
#include <algorithm>
#include <cmath>
typedef long long ll;
const int N = (int)1e6+5, mo = 9901;
ll A, B;
int p[N], num[N];
ll ans;
inline ll pow(ll x, ll n) {
x %= mo;
ll tmp = x, ret = 1;
while(n) {
if(n&1) ret = (ret*tmp)%mo;
tmp = (tmp*tmp)%mo;
n >>= 1;
}
return ret;
}
inline ll Sum(ll x, ll n) {return (pow(x,n+1)-1)*pow(x-1,mo-2)%mo;}
inline ll Re() {
ll x = 0; char ch=getchar(); bool f = 0;
for(; ch>'9'||ch<'0'; ch=getchar()) if(ch=='-') f = 1;
for(; ch>='0'&&ch<='9'; ch=getchar()) x = (x<<1)+(x<<3)+ch-48;
if(f) return -x;
return x;
}
inline void prework() {
int lim = (int)sqrt(A);
for(int i=2;i<=lim;++i)
if(A%i==0) {
p[++p[0]] = i;
while(A%i==0) {
num[p[0]]++;
A /= i;
}
}
if(A>1) {
p[++p[0]] = A;
num[p[0]] = 1;
}
}
int main() {
A = Re(); B = Re();
prework();
ans = 1;
for(int i=1;i<=p[0];++i) ans = ans*Sum(p[i],num[i]*B)%mo;
printf("%lld\n",ans);
return 0;
}