【SSOJ 2913: 「一本通 6.4 例 3」Sumdiv】题解
题目
原题来自:Romania OI 2002
求 \(A^B\) 的所有约数之和 \(\bmod 9901\)。
思路
首先按照算术基本定理:
\[\Large A=p_1^{k_1}\times p_2^{k_2}\times\cdots\times p_n^{k_n}
\]
所以:
\[\Large A^B=p_1^{k_1\times B}\times p_2^{k_2\times B}\times\cdots\times p_n^{k_n\times B}
\]
然后根据约数和公式:
\[\Large ans=(p_1^0+p_1^1+\cdots+p_1^{k_1\times B})\times (p_2^0+p_2^1+\cdots+p_2^{k_2\times B})\times\cdots\times(p_n^0+p_n^1+\cdots+p_n^{k_n\times B})
\]
然后根据等比数列求和公式:
\[\Large ans=\frac{p_1^{k_1\times B+1}-1}{p_1-1}\times \frac{p_2^{k_2\times B+1}-1}{p_2-1}\times\cdots \times\frac{p_n^{k_n\times B+1}-1}{p_n-1}
\]
然后就解出来了。
总结
这是一道非常综合的题,考察知识点主要有四个:
- 算术基本定理(质因数分解)
- 约数和公式
- 等比数列求和公式
- 求逆元(费马小定理+快速幂)
每一个知识点都尤为重要,只要懂得这些知识点,这道题就迎刃而解了。
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define N
//#define M
#define mo 9901
int n, m=1, i, j, k;
int a, b;
int kuai(int a, int b)
{
int ans=1;
while(b)
{
if(b&1) ans=(ans*a)%mo;
a=(a*a)%mo;
b>>=1;
}
return ans;
}
int deng(int x, int n)
{
return (kuai(x, n+1)-1)*kuai(x-1, mo-2)%mo;
}
signed main()
{
// freopen("tiaoshi.in","r",stdin);
// freopen("tiaoshi.out","w",stdout);
a=read(); b=read();
for(i=2; i<=a; ++i)
if(a%i==0)
{
k=0; while(a%i==0) ++k, a/=i;
// printf("deng(%lld, %lld)=%lld\n", i, k*b, deng(i, k*b));
m*=deng(i, k*b);
m%=mo;
}
printf("%lld", (m%mo+mo)%mo);
return 0;
}
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/15817137.html