• 杜教筛&Min_25筛学习笔记


    杜教筛

    这个东西已经咕了差不多半年QAQ
    然后现在才开始写.

    有的时候,我们需要完成这样一个问题.
    (sum_{i=1}^nf(i)).其中(f)是积性函数.
    (nleq 10^7)时,可以用线性筛解决这个问题.
    然而,起源于(Project Eular)的这个黑科技可以把(n)的范围扩展到(10^{11})左右.

    考虑狄利克雷卷积.
    假设(f*g=h),那么写成狄利克雷卷积的形式,就是

    [sum_{i=1}^nh(i)=sum_{i=1}^nsum_{d|i}f(i)g(frac{i}{d})\ =sum_{d=1}^ng(d)sum_{i=1}^{lfloorfrac{n}{d} floor}f(i)\ =sum_{d=1}^ng(d)S(lfloorfrac{n}{d} floor)\ 把第一项拉出来,得\ g(1)S(n)=sumlimits_{i=1}^{n}g(i)S(lfloorfrac{n}{i} floor)-sumlimits_{i=2}^{n}g(i)S(lfloorfrac{n}{i} floor) ]

    考虑到(lfloorfrac{n}{d} floor)只有(sqrt n)种取值,于是记忆化搜索一波,美滋滋.
    因此,只要可以快速求(h)的前缀和与(g),就可以快速求(f)的和.

    时间复杂度大约是(O(n^{frac{3}{4}})),可以用积分证.

    下面举几个栗子.

    莫比乌斯函数

    我们知道(mu*1=e),而(sum h=1),因此就很好求啦.
    在存储上也有一个小优化,无需(map).考虑到求出的每个(S(x)),(x)都是(n)的因数且(frac{n}{x})不大,因此只需如下代码即可.

    LL calc_miu(int x){
        if(x<maxn)return miu[x];
        else if(w2[n/x])return w2[n/x];
        LL ans=1;
        for(int i=2,ed;i<=x;i=ed+1)
        ed=x/(x/i),ans-=(ed-i+1)*calc_miu(x/i);
        return w2[n/x]=ans;
    }
    
    欧拉函数

    我们知道(varphi*1=id),因此(sum h=frac{n*(n-1)}{2}),就很好求啦.
    代码如下

    LL calc_phi(int x){
        if(x<maxn)return phi[x];
        else if(w1[n/x])return w1[n/x];
        LL ans=(LL)x*(LL)(x+1)/2;
        for(int i=2,ed;i<=x;i=ed+1)
        ed=x/(x/i),ans-=(ed-i+1)*calc_phi(x/i);
        return w1[n/x]=ans;
    }
    

    Min_25筛

    待UPD

  • 相关阅读:
    eclipse的下载安装
    找不到符号 类string
    [转]Android_开源框架_AndroidUniversalImageLoader网络图片加载
    [转]移动web开发经验总结
    测试一下吧
    javascript 的 encodeURIComponent 函数用 Objective-C 实现
    几个Objective-C的HTML解析库
    html test
    一段测试代码
    [转]Embed WebView in Fragment
  • 原文地址:https://www.cnblogs.com/Romeolong/p/10062106.html
Copyright © 2020-2023  润新知