题目简介
Description | 题目描述
Consider two natural numbers \(A\) and \(B\). Let \(S\) be the sum of all natural divisors of \(A^B\). Determine \(S\) modulo \(9901\) (the rest of the division of \(S\) by \(9901\)).
给定两个自然数\(A\)和\(B\),\(S\)为\(A^B\)的所有正整数约数和,编程输出\(S\) \(mod\) \(9901\)的结果。
Input | 输入
The only line contains the two natural numbers \(A\) and \(B\), (\(0\leq A,B \leq 50000000\))separated by blanks.
只有一行,两个用空格隔开的自然数\(A\)和\(B\)(\(0\leq A,B\leq 50000000\))。
OutPut | 输出
The only line of the output will contain \(S\) modulo \(9901\).
只有一行,即\(S\) \(mod\) \(9901\)的结果。
Sample Input | 样例输入
2 3
Sample Output | 样例输出
15
解法分析
对于自然数\(A\),一定会有:
则:
其中,\({P_k}^{a_k B}\)的正因数之和为
所以:
设 \(b=a_k B\) 如果 \(b\) 为奇数 \((b\in N,b\in O)\),那么一定有:
可倒推:
由于 \(b\) 为奇数,所以:
所以:
完美成立
如果 \(b\) 为偶数 \((b\in N,b\in E)\),那么一定有:
同理推导:
所以:
完美成立
而 \(Sum({P_k}^{\frac{b}{2}})\) 又可以由此不断继续分下去
由此,整个问题化解成了 简单的 快速幂+分治
代码
解决这些数学问题后,最后的问题就是long long了
使用 \(p\) 数组存 \(P_k\) , \(a\) 数组存 \(a_k\)
for(int i=2;i<=A;i++){
if(A%i)continue;
p[++n]=i;
while(!(A%i)){
a[n]++;
A/=i;
}
}
快速幂(非递归实现):
inline ll power(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans%mod;
}
分治(很短的):
inline ll sum(ll c,ll k){
if(!k)return 1;
int ret;
if(k&1)
ret=(power(c,(k>>1)+1)+1)*sum(c,k>>1)%mod;
else ret=((power(c,k>>1)+1)*sum(c,k>>1)-power(c,k>>1))%mod;
return ret%mod;
}
综合起来看就是:
#include<bits/stdc++.h>
typedef long long ll;
const int maxn=10000010;
const int mod=9901;
inline ll power(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans%mod;
}
int A,B;
int p[maxn],a[maxn];
int n;
inline ll sum(ll c,ll k){
if(!k)return 1;
int ret;
if(k&1)
ret=(power(c,(k>>1)+1)+1)*sum(c,k>>1)%mod;
else ret=((power(c,k>>1)+1)*sum(c,k>>1)-power(c,k>>1))%mod;
return ret%mod;
}
int main(){
scanf("%d%d",&A,&B);
for(int i=2;i<=A;i++){
if(A%i)continue;
p[++n]=i;
while(!(A%i)){
a[n]++;
A/=i;
}
}
ll S=1;
for(int i=1;i<=n;i++){
S=(S*sum(p[i],a[i]*B))%mod;
}
printf("%lld\n",S);
return 0;
}
$$-----END-----$$