• 杜教筛 模板


    转自:

     http://blog.leanote.com/post/totziens/%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%8F%8D%E6%BC%94%E4%B8%8E%E6%9D%9C%E6%95%99%E7%AD%9B

    1. 求$sumlimits_{i=1}^nmu(i),nleqslant 10^{11}$
    直接求不好求,但是我们有$sumlimits_{i=1}^nsumlimits_{d|i}mu(d)=1$
    化一下蛤:$sumlimits_{i=1}^nsumlimits_{j=1}^{leftlfloorfrac{n}{i} ight floor}mu(j)=1$,$sumlimits_{i=1}^nmu(i)=1-sumlimits_{i=2}^nsumlimits_{j=1}^{leftlfloorfrac{n}{i} ight floor}mu(j)$
    核心思想是枚举约数,这样就可以递推/递归求解了。
    时间复杂度$Oleft(n^{frac34} ight)$。
    但是注意到当$n$比较小的时候其实我们可以$O(n)$线筛出来。
    所以我们考虑分类讨论,线筛出≤B的,>B的递推。
    时间复杂度$Oleft(B+sumlimits_{i=1}^{frac nB}sqrt{frac ni} ight)=Oleft(B+frac n{sqrt{B}} ight)$

    求导一下可知在$B=n^{frac23}$时取得最小值$Oleft(n^frac23 ight)$。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<map>
     6 #define ll long long
     7 #define N 5000005
     8 using namespace std;
     9 const int inf = 5000000;
    10 map<int,ll>mp;
    11 int su[N],pr[N],tot;
    12 ll f[N];
    13 void shai()
    14 {
    15     f[1]=1;
    16     for(int i=2;i<=inf;i++)
    17     {
    18         if(!pr[i])
    19         {
    20             pr[i]=i;
    21             su[++tot]=i;
    22             f[i]=i-1;
    23         }
    24         for(int j=1;j<=tot&&su[j]<=pr[i]&&su[j]*i<=inf;j++)
    25         {
    26             pr[su[j]*i]=su[j];
    27             if(su[j]==pr[i])f[su[j]*i]=f[i]*su[j];
    28             else f[su[j]*i]=f[i]*(su[j]-1);
    29         }
    30     }
    31     for(int i=1;i<=inf;i++)
    32     {
    33         f[i]=f[i-1]+f[i];
    34     }
    35     return ;
    36 }
    37 int n;
    38 ll phi(int x)
    39 {
    40     if(x<=inf)return f[x];
    41     if(mp.find(x)!=mp.end())return mp[x];
    42     ll as=1LL*x*(x+1)/2;int r;
    43     for(int l=2;l<=x;l=r+1)
    44     {
    45          r=x/(x/l);
    46         as-=phi(x/l)*(r-l+1);
    47     }
    48     return mp[x]=as;
    49 }
    50 int main()
    51 {
    52     shai();
    53     scanf("%d",&n);
    54     printf("%lld
    ",phi(n));
    55     return 0;
    56 }
    57 

     

  • 相关阅读:
    Death Race
    中国队吃中药了?
    (zt)让我们相亲相爱一百年不动摇
    Subversion & Arfa Karim Randhawa
    要是有时间的话……
    (zt)山王
    (zt)东方红
    Oracle 备份 与 恢复 概述
    Solaris 网络 配置
    RAID 磁盘阵列 详解
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6679971.html
Copyright © 2020-2023  润新知