题目大意:
给出 A,B A , B ,求 AB A B 的约数之和 mod m o d 9901 9901 。
1 1 ≤≤ 5∗107 5 ∗ 10 7
分析:
对
A
A
进行质因数分解,可得:
则我们可以推出
AB
A
B
可表达为:
p1B∗c1p2B∗c2……pmB∗cm
p
1
B
∗
c
1
p
2
B
∗
c
2
…
…
p
m
B
∗
c
m
则
AB
A
B
的约数和可以表示为:
(1+p1+p12+……+p1B∗c1)∗(1+p2+p22+……+p2B∗c2)∗……∗(1+pm+pm2+……+pmB∗cm)
(
1
+
p
1
+
p
1
2
+
…
…
+
p
1
B
∗
c
1
)
∗
(
1
+
p
2
+
p
2
2
+
…
…
+
p
2
B
∗
c
2
)
∗
…
…
∗
(
1
+
p
m
+
p
m
2
+
…
…
+
p
m
B
∗
c
m
)
我们设
x为任意一个
(1+pi+pi2+……+piB∗ci)
(
1
+
p
i
+
p
i
2
+
…
…
+
p
i
B
∗
c
i
)
,
可以发现
x在
pi进制下
p
i
进
制
下
的表示为一个长为
B∗ci+1
B
∗
c
i
+
1
的数且每一位都是
1
1
那么我们要求的即为
一个在长为
B∗ci+1
B
∗
c
i
+
1
的且每一位都是
pi−1
p
i
−
1
/
(pi−1)
(
p
i
−
1
)
的数
那么显然这个数为
piB∗ci+1−1
p
i
B
∗
c
i
+
1
−
1
那么显然x 为
(piB∗ci+1−1)/(pi−1)mod
(
p
i
B
∗
c
i
+
1
−
1
)
/
(
p
i
−
1
)
m
o
d
9901
9901
那么我们就可以用快速幂去求出
piB∗ci+1
p
i
B
∗
c
i
+
1
,
对于
/(pi−1)
/
(
p
i
−
1
)
因为
9901
9901
为素数,
所以我们当
(pi−1)
(
p
i
−
1
)
不是
9901
9901
倍数的时候,可以直接计算其的乘法逆元,
而如果为其倍数,那么我们可以发现
pi
p
i
mod
m
o
d
9901=1
9901
=
1
那么我们回到一开始的算式
(pi+pi+pi2+……+piB∗ci)
(
p
i
+
p
i
+
p
i
2
+
…
…
+
p
i
B
∗
c
i
)
显然
(pi+pi+pi2+……+piB∗ci)=
(
p
i
+
p
i
+
p
i
2
+
…
…
+
p
i
B
∗
c
i
)
=
B∗ci+1
B
∗
c
i
+
1
(mod
(
m
o
d
9901)
9901
)
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define modn 9901
#define N 25
using namespace std;
typedef long long LL;
int a, b, num, cnt[N][2];
void divide(int x){
num = 0;
for (int i = 2; i * i <= x; i++){
if (x % i == 0){
cnt[++num][0] = i;
while (x % i == 0) x /= i, cnt[num][1]++;
}
}
if (x != 1) cnt[++num][0] = x, cnt[num][1] = 1;
}
int ksm(int a, LL b){
int rp = 1;
for (; b ; b >>= 1){
if (b & 1) rp =(LL) rp * a % modn;
a = (LL) a * a % modn;
}
return rp;
}
int main(){
scanf("%d %d", &a, &b);
divide(a);
int ans = 1;
for (int i = 1; i <= num; i++)
if ((cnt[i][0] - 1) % modn == 0)
ans = ((LL)b * cnt[i][1] + 1) % modn * ans % modn;
else {
int x = ksm(cnt[i][0], (LL)cnt[i][1] * b + 1);
x = (x - 1 + modn) % modn;
int y = ksm(cnt[i][0] - 1, modn - 2);
ans = (LL)ans * x % modn * y %modn;
}
printf("%d\n", ans);
return 0;
}