[SDOI 2012]Longge的问题

Description

Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。

Input

一个整数,为N。

Output

一个整数,为所求的答案。

Sample Input

6

Sample Output

15

HINT

【数据范围】
对于60%的数据,0<N<=2^16。
对于100%的数据,0<N<=2^32。

题解

求 $$\sum_{i = 1}^N gcd(i, N)$$

用惯用的套路我们枚举 $N$ 的因子  $$\sum_{d \mid N} d \cdot \sum_{i = 1}^{ \frac{N}{d} } \left[gcd \left( \frac{N}{d} , i \right) = 1\right]$$

化简为 $$\sum_{d \mid N} d \cdot \varphi \left( \frac{N}{d} \right)$$

欧拉函数直接用 $\varphi(n) = n \cdot \prod_{i = 1}^k \left(1-\frac{1}{p_i} \right)$ 来求。

 1 //It is made by Awson on 2018.1.12
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <cstdio>
 9 #include <string>
10 #include <vector>
11 #include <cstdlib>
12 #include <cstring>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Max(a, b) ((a) > (b) ? (a) : (b))
17 #define Min(a, b) ((a) < (b) ? (a) : (b))
18 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
19 using namespace std;
20 void read(LL &x) {
21     char ch; bool flag = 0;
22     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
23     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
24     x *= 1-2*flag;
25 }
26 void write(LL x) {
27     if (x > 9) write(x/10);
28     putchar(x%10+48);
29 }
30 
31 LL n, m, ans;
32 
33 LL phi(LL x) {
34     LL ans = x;
35     for (LL i = 2; i <= m; i++) {
36     if (x%i) continue;
37     ans = ans*(i-1)/i;
38     while (!(x%i)) x /= i;
39     }
40     if (x > 1) ans = ans*(x-1)/x;
41     return ans;
42 }
43 void work() {
44     read(n); m = sqrt(n);
45     for (LL i = 1; i <= m; i++) {
46     if (n%i) continue;
47     ans += i*phi(n/i);
48     if (i*i < n) ans += n/i*phi(i);
49     }
50     write(ans);
51 }
52 int main() {
53     work();
54     return 0;
55 }

 

posted @ 2018-01-12 15:54  NaVi_Awson  阅读(234)  评论(0编辑  收藏  举报