zoukankan      html  css  js  c++  java
  • 杜教筛&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

  • 相关阅读:
    任务26:dotnet watch run 和attach到进程调试
    我心中的ASP.NET Core 新核心对象WebHost(二)
    任务25:IHostEnvironment和 IApplicationLifetime介绍
    跨域之jsonp
    H5之拖拽
    h5学习之表单
    canvas之五角星的绘制
    canvas学习之初级运用
    js中常见继承方式
    this指针的使用场景
  • 原文地址:https://www.cnblogs.com/Romeolong/p/10062106.html
Copyright © 2011-2022 走看看