POJ1845 Sumdiv [数论,逆元]

Posted cytus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1845 Sumdiv [数论,逆元]相关的知识,希望对你有一定的参考价值。

  题目传送门

Sumdiv

Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 26041   Accepted: 6430

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).

Input

The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.

Output

The only line of the output will contain S modulo 9901.

Sample Input

2 3

Sample Output

15

Hint

2^3 = 8. 
The natural divisors of 8 are: 1,2,4,8. Their sum is 15. 
15 modulo 9901 is 15 (that should be output). 

Source


  分析:

  题意就是求A^B在mod 9901下的约数和。

  之前遇到过一个一模一样的题,直接分解质因数,把每一个质因数按照费马小定理对9901-1取模然后直接暴力计算就过了,但是在这里死活过不了。然后稍微推了一下发现这么做有BUG,因为9900不是质数,取模的时候会出错。

  然后翻了一下lyd的书,正解思路了解一下。

  同样先分解质因数,再由约数和定理ans=(1+q1+q1^2+...+q1^(c1*b))*(1+q2+q2^2+...+q2^(c2*b))*...*(1+qn+qn^2+...qn^(cn*b))可得,对于每一个质因数qi,求(1+qi+qi^2+...+qi^(ci*b))时,可以用等比数列的求和公式求,即(qi^(b*ci+1))/(qi-1),但是除法并不满足取模的分配律,所以就用逆元来代替。也就是求1/(qi-1)在模9901下的逆元。但是要注意,qi-1可能被9901整除,此时不存在逆元。不过可以发现,此时qi mod 9901=1,那么(1+qi+qi^2+...+qi^(b*ci))=1+1+1+...+1(b*ci+1个1),特判即可。

  Code:

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<iomanip>
 7 #include<algorithm>
 8 using namespace std;
 9 typedef long long ll;
10 const ll mod=9901;
11 const ll N=5e6+7;
12 ll A,B,q[N],f[N],ans,tot,cnt;
13 void fenjie()
14 {
15     for(ll i=2;i*i<=A;i++){
16         if(A%i==0){
17             q[++cnt]=i;
18             while(A%i==0){
19             f[cnt]++;A/=i;}
20         }
21     }
22     if(A>1)q[++cnt]=A,f[cnt]++;
23 }
24 inline ll power(ll x,ll y)
25 {
26     ll ret=1;
27     while(y>0){
28         if(y&1)ret=(ret*x)%mod;
29         x=(x*x)%mod;y>>=1;}
30     return ret;
31 }
32 void work()
33 {
34     fenjie();ans=1;
35     for(int i=1;i<=cnt;i++){
36         if((q[i]-1)%mod==0){
37             ans=(ans*(B*f[i]+1)%mod)%mod;
38             continue;}
39         ll x=power(q[i],B*f[i]+1);
40         x=(x-1+mod)%mod;
41         ll y=power(q[i]-1,mod-2);
42         ans=(ans*x*y)%mod;
43     }
44     printf("%lld",ans);
45 }
46 int main()
47 {
48     cin>>A>>B;
49     work();return 0;
50 }

 

 

 

以上是关于POJ1845 Sumdiv [数论,逆元]的主要内容,如果未能解决你的问题,请参考以下文章

题解POJ1845 Sumdiv(乘法逆元+约数和)

poj 1845 Sumdiv(约数和,乘法逆元)

POJ_1845_Sumdiv

POJ1845 Sumdiv - 乘法逆元+快速幂A^B的约数个数和

POJ 1845Sumdiv——数论 质因数 + 分治 + 快速幂

poj1845 Sumdiv