Step 1.
设 S = A B S=A^B S=AB 的约数和。
约数和公式:
设 a = ∑ i = 1 n p i k i a=\sum\limits_{i=1}^n p_i^{k_i} a=i=1∑npiki( p i ∈ P , k i ∈ Z + p_i\in\Bbb{P},k_i\in\Bbb{Z^+} pi∈P,ki∈Z+),即对 a a a 分解素因数,
则 a a a 的约数和 = ∏ i = 1 n ∑ j = 0 k i p i j = ( 1 + p 1 + p 1 2 + . . . + p 1 k 1 ) ( 1 + p 2 + p 2 2 + . . . + p 2 k 2 ) . . . ( 1 + p i + p i 2 + . . . + p i k i ) =\prod\limits_{i=1}^n\sum\limits_{j=0}^{k_i}p_i^j=(1+p_1+p_1^2+...+p_1^{k_1})(1+p_2+p_2^2+...+p_2^{k_2})...(1+p_i+p_i^2+...+p_i^{k_i}) =i=1∏nj=0∑kipij=(1+p1+p12+...+p1k1)(1+p2+p22+...+p2k2)...(1+pi+pi2+...+piki)。
设 A = ∑ i = 1 n p i k i A=\sum\limits_{i=1}^n p_i^{k_i} A=i=1∑npiki( p i ∈ P , k i ∈ Z + p_i\in\Bbb{P},k_i\in\Bbb{Z^+} pi∈P,ki∈Z+),即对 A A A 分解素因数。
S = ∏ i = 1 n ( 1 + p i 1 + p i 2 + . . . + p i k i ⋅ B ) \begin{aligned} S=\prod\limits_{i=1}^n(1+p_i^1+p_i^2+...+p_i^{k_i\cdot B}) \end{aligned} S=i=1∏n(1+pi1+pi2+...+piki⋅B)
Step 2.
可以发现这个东西是个等比数列。
等比数列求和公式:
设等比数列 { a 1 , a 2 , . . . } , a i a i − 1 = q \{a_1,a_2,...\},\frac{a_i}{a_i-1}=q {a1,a2,...},ai−1ai=q,
则 ∑ i = 1 n = a 1 × q n − 1 q − 1 \sum\limits_{i=1}^n=a_1\times\displaystyle\frac{q^n-1}{q-1} i=1∑n=a1×q−1qn−1。
S = ∏ i = 1 n ( 1 + p i 1 + p i 2 + . . . + p i k i ⋅ B ) = ∏ i = 1 n p i k i ⋅ B + 1 − 1 p i − 1 ≡ ∏ i = 1 n p i k i ⋅ B + 1 − 1 p i − 1 ( m o d p ) \begin{aligned} S&=\prod\limits_{i=1}^n(1+p_i^1+p_i^2+...+p_i^{k_i\cdot B})\\&=\prod\limits_{i=1}^n\displaystyle\frac{p_i^{k_i\cdot B+1}-1}{p_i-1} \\&\equiv\prod\limits_{i=1}^n\displaystyle\frac{p_i^{k_i\cdot B+1}-1}{p_i-1}\quad(\bmod~p) \end{aligned} S=i=1∏n(1+pi1+pi2+...+piki⋅B)=i=1∏npi−1piki⋅B+1−1≡i=1∏npi−1piki⋅B+1−1(mod p)
Step 3.
柿子推好了,接下来是计算。分子简单,快速幂一下就行。分母呢?如果 p i − 1 p_i-1 pi−1 与 p p p 互素,可以算逆元,但如果两数不互素怎么办?
如果两数不互素,因为
p
p
p 是质数,所以两数的
gcd
\gcd
gcd 只能是
p
p
p,所以
p
∣
p
i
−
1
p|p_i-1
p∣pi−1,此时:
p
i
≡
1
(
m
o
d
p
)
p_i\equiv1(\bmod~p)
pi≡1(mod p)
这不就简单多了吗?直接带到
1
+
p
i
1
+
p
i
2
+
.
.
.
+
p
i
k
i
⋅
B
1+p_i^1+p_i^2+...+p_i^{k_i\cdot B}
1+pi1+pi2+...+piki⋅B 中去:
1
+
p
i
1
+
p
i
2
+
.
.
.
+
p
i
k
i
⋅
B
≡
1
+
1
+
1
+
.
.
.
+
1
≡
k
i
×
B
+
1
(
m
o
d
p
)
\begin{aligned} 1+p_i^1+p_i^2+...+p_i^{k_i\cdot B}&\equiv1+1+1+...+1\\&\equiv k_i\times B+1\quad(\bmod~p) \end{aligned}
1+pi1+pi2+...+piki⋅B≡1+1+1+...+1≡ki×B+1(mod p)
Step 4.
代码逻辑:
- 对 A A A 分解质因数, A = ∑ i = 1 n p i k i A=\sum\limits_{i=1}^n p_i^{k_i} A=i=1∑npiki;
- 对于每个 p i p_i pi,若 p i ≡ 1 ( m o d p ) p_i\equiv1(\bmod~p) pi≡1(mod p),算出 k i × B + 1 m o d p k_i\times B+1\bmod p ki×B+1modp;否则算出 p i k i ⋅ B + 1 − 1 m o d p p_i^{k_i\cdot B+1}-1\bmod p piki⋅B+1−1modp 和 p i − 1 p_i-1 pi−1 在膜 p p p 意义下的乘法逆元,带入柿子算算就行。
记得 long long
。
//acwing97
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1000, mod = 9901;
ll p[N], k[N], cnt, ans = 1;
ll qpow(ll a, ll b){
ll ans = 1;
while(b){
if(b&1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
ll inv(ll a){
return qpow(a, mod-2);
}
int main(){
ll a, b;
scanf("%lld%lld", &a, &b);
ll tmp = a;
for(ll i = 2; i <= a; ++ i)
if(tmp % i == 0){
p[++cnt] = i;
while(tmp % i == 0) tmp /= i, ++ k[cnt];
}
if(tmp > 1) p[++cnt] = tmp, k[cnt] = 1;
// for(int i = 1; i <= cnt; ++ i) printf("%d %d\n", p[i], k[i]);
for(int i = 1; i <= cnt; ++ i)
if(p[i] % mod == 1) ans = ans * (k[i]*b + 1) % mod;
else ans = ans * (qpow(p[i], k[i]*b+1)+mod-1) % mod * inv(p[i]-1) % mod;
if(a == 0) ans = 0;
printf("%lld\n", ans);
return 0;
}