杜教筛&Min_25筛学习笔记

杜教筛

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

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

考虑狄利克雷卷积.
假设\(f*g=h\),那么写成狄利克雷卷积的形式,就是
\[\sum_{i=1}^nh(i)=\sum_{i=1}^n\sum_{d|i}f(i)g(\frac{i}{d})\\ =\sum_{d=1}^ng(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}f(i)\\ =\sum_{d=1}^ng(d)S(\lfloor\frac{n}{d}\rfloor)\\ 把第一项拉出来,得\\ g(1)S(n)=\sum\limits_{i=1}^{n}g(i)S(\lfloor\frac{n}{i}\rfloor)-\sum\limits_{i=2}^{n}g(i)S(\lfloor\frac{n}{i} \rfloor) \]
考虑到\(\lfloor\frac{n}{d}\rfloor\)只有\(\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

转载于:https://www.cnblogs.com/Romeolong/p/10062106.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值