首页 > 技术文章 > POJ1485 Sumdiv

huibixiaoxing 2017-08-05 15:25 原文

Sumdiv
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 22680   Accepted: 5660

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的所有约数的和
【题解】
  把A唯一分解,不难得到答案:
   (1+p1+p1^2+……+p1^(φ1*B)) × (1+p2+p2^2+
  ……+p2^(φ2*B)) ×……× (1+pn+pn^2+……+pn^(φn*B))
  问题转化为等比数列求和,此处MOD为质数,存在逆元,但对于更一般的情况,采用分治法,复杂度多一个Log
  cal(p,k) = p^0 + p^1 + p^2 + ... + p^k
  if k&1
    cal(p,k) = (1 + p^((k + 1)/2))*cal(p, (k-1)/2)
  else
    cal(p,k) = (1 + p^(k/2)) * cal(p, k/2 - 1) + p^k
  快速幂即可
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cstdlib>
 6 #include <cmath>
 7 
 8 const int INF = 0x3f3f3f3f;
 9 const int MAXN = 50000000 + 10;
10 const int MOD = 9901;
11 
12 inline void read(int &x)
13 {
14     x = 0;char ch = getchar();char c = ch;
15     while(ch > '9' || ch < '0')c = ch, ch = getchar();
16     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
17     if(c == '-')x = -x;
18 }
19 
20 int a,b,cnt,xishu[5010],zhishu[5010],ans;
21 
22 int pow(int p, int k)
23 {
24     int r = 1, base = p;
25     for(;k;k >>= 1)
26     {
27         if(k & 1)r = ((long long)r * base) % MOD;
28         base = ((long long)base * base % MOD);
29     }
30     return r % MOD;
31 }
32 
33 //求解1 + p + p^2 + p^3 + ... + p^k 
34 int cal(int p, int k)
35 {
36     if(k == 0) return 1;
37     if(k == 1) return (p + 1) % MOD;
38     if(k & 1) return ((long long)(1 + pow(p, (k + 1)/2)) * (long long)(cal(p, (k - 1)/2))%MOD) % MOD;
39     else return((long long)(pow(p, k/2) + 1) * (long long)(cal(p, k/2 - 1)) % MOD + pow(p, k)) % MOD;
40 }
41 
42 int main()
43 {
44     read(a),read(b);
45     register int nn = sqrt(a) + 1;
46     for(register int i = 2;i <= nn && a > 1;++ i)
47         if(a % i == 0)
48         {
49             zhishu[++cnt] = i;
50             while(a % i == 0) ++ xishu[cnt], a /= i;
51         }
52     if(a > 1)zhishu[++cnt] = a, xishu[cnt] = 1;
53     ans = 1;
54     for(register int i = 1;i <= cnt;++ i)
55     {
56         ans *= cal(zhishu[i], xishu[i] * b);
57         ans %= MOD;
58     } 
59     printf("%d", ans%MOD);
60     return 0;
61 }
POJ1848 Sumdiv

推荐阅读