• BZOJ2705 [SDOI2012]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。

     

    题解

    $$egin{aligned}
    &sum_{i=1}^N gcd(i, N)\
    &= sum_{d|N} dsum_{i=1}^N [gcd(i, N) = d]\
    &= sum_{d|N} dsum_{d|t} muleft(frac td ight)sum_{i=1}^N [t|gcd(i,N)]\
    &= sum_{t|N} frac Ntsum_{d|t} dmuleft(frac td ight)\
    &= sum_{t|N} frac Ntphi(t)
    end{aligned}$$
    预处理N的质因子,枚举其因数即可。

    代码:

    #include <cstdio>
    typedef long long LL;
    const int M = 100;
    int n;
    LL ans;
    int pr[M], prcnt;
    inline void calc(int x) {
      int anst = x;
      for (int i = 0; i < prcnt; ++i) if (!(x % pr[i]))
        anst = anst / pr[i] * (pr[i] - 1);
      ans += (LL)n / x * anst;
    }
    int main() {
      scanf("%d", &n);
      int tn = n;
      for (int i = 2; (LL)i * i <= tn; ++i)
        if (!(tn % i)) {
          pr[prcnt++] = i;
          while (!(tn % i)) tn /= i;
        }
      if (tn > 1)
        pr[prcnt++] = tn;
      for (int i = 1; (LL)i * i <= n; ++i) if (!(n % i)) {
        calc(i);
        if (i != n / i) calc(n / i);
      }
      printf("%lld
    ", ans);
      return 0;
    }
    

      

  • 相关阅读:
    ant
    Java中的值传递和引用传递
    待解决的问题
    Ant生成文件解析
    JUnit初学
    遍历枚举
    2013年5月阅读链接
    《C Primer Plus》阅读笔记(3)
    《C Primer Plus》阅读笔记(2)
    《C Primer Plus》阅读笔记(4)
  • 原文地址:https://www.cnblogs.com/y-clever/p/7371347.html
Copyright © 2020-2023  润新知