题目链接:Sumdiv
题意:给定两个自然数A,B,定义S为A^B所有的自然因子的和,求出S mod 9901的值。
题解:了解下以下知识点
1.整数的唯一分解定理
任意正整数都有且只有唯一的方式写出其质因子的乘积表达式
$A={p_1}^{k_1}*{p_2}^{k_2}*{p_3}^{k_3}*...*{p_n}^{k_n}$
2.整数因数个数
$B=(k_1+1)*(k_2+1)*(k_3+1)...*(k_n+1)$
3.整数因数总和
$S=(1+p_1+p_1^2+p_1^3+...+{p_1}^{k_1})*(1+p_2+p_2^2+p_2^3+...+{p_2}^{k_2})*...(1+p_n+p_n^2+p_n^3+...+{p_n}^{k_n})$
明显地:先分解整数A,A的整数因数总和能表示,A^B只不过是pi变成pi^B。
通过等比数列求和公式:$dfrac{{p_1}^{k_1b+1}-1}{p_1-1}=1+p_1+p_1^2+p_1^3+...+{p_1}^{k_1b}$
费马小定理:
$a^{p-1} ≡1 (mod p)$
两边同除以a
$a^{p-2} ≡inv(a) (mod p)$
$inv(a) = a^{p-2} (mod p)$
快速幂求一下即可:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ll fast_mod(ll x,ll y,ll mod){ 2 ll res=1; 3 while(y){ 4 if(y&1) res=fast_mul(res,x,mod); 5 x=fast_mul(x,x,mod); 6 y>>=1; 7 } 8 return res; 9 }
直接使用快速幂可能爆long long,结合快速乘防止爆long long:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ll fast_mul(ll x,ll y,ll mod){ 2 ll res=0; 3 while(y){ 4 if(y&1) res=(res+x)%mod; 5 x=(x+x)%mod; 6 y>>=1; 7 } 8 return res; 9 }
最后一个问题,存在逆元的情况是$ax ≡1(mod p)$
如果a是p的倍数时候左边为0,明显不等于右边。可以使用这个公式
$ans=dfrac{a}{b}modm=amod(mb)/b$
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 typedef long long ll; 8 const int N=1e7; 9 const ll MOD=9901; 10 ll p[N],k[N]; 11 ll a,b,c=1; 12 13 ll fast_mul(ll x,ll y,ll mod){ 14 ll res=0; 15 while(y){ 16 if(y&1) res=(res+x)%mod; 17 x=(x+x)%mod; 18 y>>=1; 19 } 20 return res; 21 } 22 23 ll fast_mod(ll x,ll y,ll mod){ 24 ll res=1; 25 while(y){ 26 if(y&1) res=fast_mul(res,x,mod); 27 x=fast_mul(x,x,mod); 28 y>>=1; 29 } 30 return res; 31 } 32 33 void solve(){ 34 ll res=1; 35 for(ll i=1;i<c;i++){ 36 ll M=MOD*(p[i]-1); 37 res=res*(fast_mod(p[i],k[i]*b+1,M)+M-1)/(p[i]-1)%MOD; 38 } 39 printf("%lld ",(res+MOD)%MOD); 40 } 41 42 int main(){ 43 while(scanf("%lld%lld",&a,&b)!=EOF){ 44 c=1; 45 for(ll i=2;i*i<=a;i++){ 46 if(a%i==0){ 47 ll cnt=0; 48 p[c]=i; 49 while(a%i==0) a/=i,cnt++; 50 k[c]=cnt; 51 c++; 52 } 53 } 54 if(a>1) {p[c]=a;k[c]=1;c++;} 55 solve(); 56 } 57 return 0; 58 }