zoukankan      html  css  js  c++  java
  • [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 ight) = 1 ight]$$

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

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

     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 }
  • 相关阅读:
    C/C++ volatile
    Linux fopen/fread/fwrite和open/read/write
    反思 承认失败,负重前行。
    算法和数据结构 打印回形矩阵
    Linux 软链接和硬链接
    数据库 CAS原理和ABA问题
    算法和数据结构 海量数据求前K个数
    算法和数据结构 冒泡排序
    java中的经典算法之选择排序(SelectionSort)
    【Java】常量、关键字、标识符、注释
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8276082.html
Copyright © 2011-2022 走看看