zoukankan      html  css  js  c++  java
  • 【BZOJ4176】 Lucas的数论

    Description

    去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了。

    在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i的约数个数。他现在长大了,题目也变难了。
    求如下表达式的值:
     
    其中 表示ij的约数个数。
    他发现答案有点大,只需要输出模1000000007的值。

    Input

    第一行一个整数n。

    Output

     一行一个整数ans,表示答案模1000000007的值。

    Sample Input

    2

    Sample Output

    8

    HINT

     对于100%的数据n <= 10^9。

    Solution

    因为直接用编辑器打公式比较麻烦且丑,就用markdown截图完传图片了= =b。

    Code

     1 #include <cstdio>
     2 #include <cmath>
     3 
     4 #define R register
     5 const int mod = 1e9 + 7;
     6 #define maxn 1500010
     7 int miu[maxn], smiu[maxn], pr[maxn / 10], prcnt, lim, N;
     8 bool vis[maxn];
     9 int hash[maxn];
    10 bool vihash[50000];
    11 int Miu(R int n)
    12 {
    13     if (n <= lim) return smiu[n];
    14     if (vihash[N / n]) return hash[N / n];
    15     
    16     vihash[N / n] = 1;
    17     R int ret = 1;
    18     for (R int i = 2, j; i <= n; i = j + 1)
    19     {
    20         j = n / (n / i);
    21         (ret += mod - 1ll * (j - i + 1) * Miu(n / i) % mod) %= mod;
    22     }
    23     return hash[N / n] = ret;
    24 }
    25 inline int sumf(R int n)
    26 {
    27     R int ret = 0;
    28     for (R int i = 1, j; i <= n; i = j + 1)
    29     {
    30         j = n / (n / i);
    31         ret = (ret + 1ll * (j - i + 1) * (n / i)) % mod;
    32     }
    33     return ret;
    34 }
    35 int main()
    36 {
    37     scanf("%d", &N);
    38     lim = (int) pow(N * 1.0, 0.666);
    39 //    printf("%d
    ", lim);
    40     miu[1] = smiu[1] = 1;
    41     for (R int i = 2; i <= lim; ++i)
    42     {
    43         if (!vis[i]) pr[++prcnt] = i, miu[i] = -1;
    44         smiu[i] = (smiu[i - 1] + miu[i]) % mod;
    45         for (R int j = 1; j <= prcnt && 1ll * i * pr[j] <= lim; ++j)
    46         {
    47             vis[i * pr[j]] = 1;
    48             if (i % pr[j]) miu[i * pr[j]] = -miu[i];
    49             else
    50             {
    51                 miu[i * pr[j]] = 0;
    52                 break;
    53             }
    54         }
    55     }
    56     R int ans = 0, last = 0;
    57     for (R int i = 1, j; i <= N; i = j + 1)
    58     {
    59         j = N / (N / i);
    60         R int Ph = Miu(j);
    61         R int fs = sumf(N / i);
    62 //        printf("l = %d r = %d %d %d
    ", i, j, Ph, fs);
    63         ans = (ans + 1ll * (Ph - last + mod) * fs % mod * fs) % mod;
    64         last = Ph;
    65     }
    66 //    printf("%d
    ", last);
    67     printf("%d
    ", ans % mod);
    68     return 0;
    69 }
  • 相关阅读:
    Pycharm 调试system-config-users
    只写了两行代码,为什么要花两天时间?
    为开源做贡献的6个技巧
    2020年10月编程语言排行榜
    全球最厉害的 14 位程序员
    6_38_二叉树的后序遍历非递归算法(和先序有些许不一样)
    6_37_二叉树的先序遍历非递归算法
    6_36_相似二叉树
    6_33_两个一维数组判断u是否为v的子孙
    6_34_扩展判断u是否为v的子孙
  • 原文地址:https://www.cnblogs.com/cocottt/p/7101661.html
Copyright © 2011-2022 走看看