题目:POJ1845.
题目大意:给定
A
A
A和
B
B
B,求
A
B
A^B
AB的约数和,答案对
9901
9901
9901取模.
0
≤
A
,
B
≤
5
∗
1
0
7
0\leq A,B\leq 5*10^7
0≤A,B≤5∗107.
设
n
=
∏
i
=
1
k
p
i
c
i
n=\prod_{i=1}^{k}p_i^{c_i}
n=∏i=1kpici,则
n
n
n的约数和为:
σ
(
n
)
=
∏
i
=
1
k
∑
j
=
0
c
i
p
i
j
\sigma(n)=\prod_{i=1}^{k}\sum_{j=0}^{c_i}p_i^{j}
σ(n)=i=1∏kj=0∑cipij
那么我们要做的就是统计 A B A^B AB每一个质因子的数量,设 A A A含有 c n t [ i ] cnt[i] cnt[i]个质因子 i i i,那么 A B A^B AB就含有 B ∗ c n t [ i ] B*cnt[i] B∗cnt[i]个质因子 i i i,所以我们就得到了 A B A^B AB每个质因子的数量.
根据等比数列求和公式可以得出:
σ
(
n
)
=
∏
i
=
1
k
∑
j
=
0
c
i
p
i
j
=
∏
i
=
1
k
p
i
c
i
+
1
−
1
p
i
−
1
\sigma(n)=\prod_{i=1}^{k}\sum_{j=0}^{c_i}p_i^{j}= \prod_{i=1}^{k}\frac{p_i^{c_i+1}-1}{p_i-1}
σ(n)=i=1∏kj=0∑cipij=i=1∏kpi−1pici+1−1
所以我们只需要处理好对 p i − 1 p_i-1 pi−1做除法就好了,这个用费马小定理实现逆元即可.
值得注意的是,若刚好 9901 ∣ ( p i − 1 ) 9901|(p_i-1) 9901∣(pi−1),这个时候 p i − 1 p_i-1 pi−1是没有逆元的,不过我们知道这时候 p i = 1 p_i=1 pi=1,也就是说 1 + p 1 + p 1 2 + . . . p 1 b c i = b c i + 1 1+p_1+p_1^2+...p_1^{bc_i}=bc_i+1 1+p1+p12+...p1bci=bci+1.(这种情况是不可避免的,不能直接用费马小定理)
时间复杂度 O ( log n ) O(\log n) O(logn).
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=1000,mod=9901;
int a,cnt[N+9],pr[N+9],tp,ans=1;
LL b;
int power(int a,LL k){
int s=1;a%=mod;
for (;k;k>>=1,a=a*a%mod)
if (k&1) s=s*a%mod;
return s;
}
Abigail into(){
scanf("%d%lld",&a,&b); //切记指数不能取模!!!
}
Abigail work(){
int v=a;
for (int i=2;i*i<=a;++i)
if (v%i==0){
pr[++tp]=i;
while (v%i==0) v/=i,++cnt[tp];
}
if (v>1) pr[++tp]=v,cnt[tp]=1;
for (int i=1;i<=tp;++i)
if ((pr[i]-1)%mod==0) ans=(b*cnt[i]+1LL)%mod*ans%mod;
else ans=ans*power(pr[i]-1,LL(mod-2))%mod*(power(pr[i],b*cnt[i]+1LL)-1+mod)%mod;
}
Abigail outo(){
printf("%d\n",ans);
}
int main(){
into();
work();
outo();
return 0;
}