poj 1845 Sumdiv

题目描述

http://poj.org/problem?id=1845

Solution

注意到答案为 $ans=\prod_{i=1}^k \sum_{j=0}^{m\cdot a_i} p_i^j=\prod_{i=1}^k\frac{p_i^{m\cdot a_i+1}-1}{p_i-1}$

注意到模数 $9901$ 不是素数,但是这个式子一定是个整数,所以我们对 $9901\cdot(p_i-1)$ 取模再做除法即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;

const int p = 9901;

ll mul(ll x, ll n, ll p) {
ll s = 0;
for (; n; n >>= 1) {
if (n & 1) s = (s + x) % p;
x = (x + x) % p;
}
return s;
}

ll pow_mod(ll x, ll n, ll p) {
ll s = 1;
for (; n; n >>= 1) {
if (n & 1) s = mul(s, x, p);
x = mul(x, x, p);
}
return s;
}

int n, k;

ll a[1010], cnt, b[1010];

ll ans;

void init() {
cnt = 0; ans = 1;
fill(a, a + 1010, 0);
}

void work() { init();
for (int i = 2; i * i <= n; ++i) {
if (n % i) continue; b[++cnt] = i;
while (n % i == 0) n /= i, ++a[cnt];
a[cnt] *= k;
}
if (n > 1) a[++cnt] = k, b[cnt] = n;
for (int i = 1; i <= cnt; ++i) {
ll t = p * (b[i] - 1);
ans = ans * (pow_mod(b[i], a[i] + 1, t) + t - 1) % t / (b[i] - 1) % p;
}
cout << ans << "\n";
}


int main() {
while (cin >> n >> k) work();
return 0;
}

另外我们注意到 $\sum_{i=0}^k p^i$ 这个东西可以递归处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;

const int p = 9901;

ll pow_mod(ll x, ll n) {
ll s = 1;
for (; n; n >>= 1) {
if (n & 1) s = s * x % p;
x = x * x % p;
}
return s;
}

int n, k;

ll a[1010], cnt, b[1010];

int solve(int a, int n) {
if (n == 0) return 1;
if (n & 1) return solve(a, n / 2) * (1 + pow_mod(a, n / 2 + 1)) % p;
else return (solve(a, n / 2 - 1) * (1 + pow_mod(a, n / 2 + 1)) + pow_mod(a, n / 2)) % p;
}

ll ans;

void init() {
cnt = 0; ans = 1;
fill(a, a + 1010, 0);
}

void work() { init();
for (int i = 2; i * i <= n; ++i) {
if (n % i) continue; b[++cnt] = i;
while (n % i == 0) n /= i, ++a[cnt];
a[cnt] *= k;
}
if (n > 1) a[++cnt] = k, b[cnt] = n;
for (int i = 1; i <= cnt; ++i)
ans = ans * solve(b[i], a[i]) % p;
cout << ans << "\n";
}


int main() {
while (cin >> n >> k) work();
return 0;
}