杜教筛Powerful Number_算法
JueFan 一只绝帆

杜教筛

推导过程

设现在要求积性函数 f(x)f(x) 的前缀和 S(x)S(x)

用取整函数 [x][x] 表示下取整 x\lfloor x\rfloor,太懒了。

我们再构造一个函数 gg(不需要积性),考虑 fgf*g 的前缀和:

i=1n(fg)(i)=i=1ndif(id)g(d)=d=1ni=1[nd]f(i)g(d)=d=1ng(d)S([nd])\begin{aligned}\sum_{i=1}^n(f*g)(i)&=\sum_{i=1}^n\sum_{d\mid i}f\left(\frac id\right)g(d)\\&=\sum_{d=1}^n\sum_{i=1}^{[\frac n d]}f(i)g(d)\\&=\sum_{d=1}^ng(d)S\left(\left[\frac n d\right]\right)\end{aligned}


观察得:

g(1)S(n)=i=1ng(i)S([ni])i=2ng(i)S([ni])=(fg)(n)i=2ng(i)S([ni])\begin{aligned} g(1)S(n)&=\sum_{i=1}^ng(i)S\left(\left[\frac n i\right]\right)-\sum_{i=2}^ng(i)S\left(\left[\frac n i\right]\right) \\&=(f*g)(n)-\sum_{i=2}^ng(i)S\left(\left[\frac n i\right]\right) \end{aligned}

由于第一项本身是有一个 S(n)S(n) 的,现在我们利用上面的构造把 S(n)S(n) 去掉后,后面的一项就只需要我们求出 n\sqrt nSS 的值即可。

S(n)=(fg)(n)i=2ng(i)S([ni])g(1)S(n)=\frac{(f*g)(n)-\sum_{i=2}^ng(i)S([\frac{n}{i}])}{g(1)}

gg 为积性函数时 g(1)=1g(1)=1

S(n)=(fg)(n)i=2ng(i)S([ni])S(n)=(f*g)(n)-\sum_{i=2}^ng(i)S\left(\left[\frac n i\right]\right)

所以杜教筛把难点规约到了一个点:

  • 找到 gg 使得 ggfgf*g 的前缀和易求。

不会分析复杂度,但可以证明:预处理 Θ(n23)\Theta(n^{\frac 2 3}) 项时,复杂度为 Θ(n23)\Theta(n^{\frac 2 3})

P4213 【模板】杜教筛

TT 次求 i=1nφ(i)\sum_{i=1}^n\varphi(i)i=1nμ(i)\sum_{i=1}^n\mu(i)

T10,n231T\le 10,n\le2^{31}

μI=ϵ,φI=id\mu*I=\epsilon,\varphi*I=id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
auto DJ=[](auto &&DJ,ll n,auto &mp,auto &&Sf,auto &&Sg,auto &&S)->ll{
if(n<=B) return Sf[n];
if(mp.count(n)) return mp[n];
ll &ans=mp[n]=S(n);
for(ll l=2,r;l<=n;l=r+1) {
r=n/(n/l);
ans-=(Sg(r)-Sg(l-1))*DJ(DJ,n/l,mp,Sf,Sg,S);
} return ans;
};
main:
printf("%lld %lld\n",
DJ(DJ,n,mp_phi,phi,[](ll n){return n;},[](ll n){return n*(n+1)/2;}),
DJ(DJ,n,mp_mu,mu,[](ll n){return n;},[](ll n){return 1;})
);

P3768 简单的数学题

求:

i=1nj=1nij(i,j)\sum_{i=1}^n\sum_{j=1}^n ij (i,j)

n1010n\le 10^{10}

略去复杂的莫反过程,我们要快速求 x=1nx2φ(x)\sum_{x=1}^nx^2\varphi(x),设 f(x)=x2φ(x)f(x)=x^2\varphi(x)

有意思的一点是:idcgidc=idc(gI)id^cg*id^c=id^c(g*I)

dxdcg(d)(xd)c=xcdxg(d)I(xd)\begin{aligned} \\\sum_{d|x}d^cg(d)\left(\frac{x}{d}\right)^c=x^c\sum_{d|x}g(d)I\left(\frac x d\right) \end{aligned}

利用这个技巧,我们构造 g(x)=x2g(x)=x^2,则 fg=id2(φI)=id3f*g=id^2(\varphi*I)=id^3

推导过程略去,x=1nx3=n2(n+1)24\sum_{x=1}^n x^3=\frac{n^2(n+1)^2}{4}

考场上急需自然数幂和的公式实在不行就打个高斯消元。

注:整除分块套杜教筛跑 101010^{10} 是没有任何问题的,因为杜教筛会计算 n,[n2],[n3],n,[\frac n 2],[\frac n 3],\cdots,所以整除分块其实只是在查表而已。

同理,这告诉我们,杜教筛套杜教筛(即 fg\sum f*gg\sum g 也使用杜教筛来算)是复杂度不变的!

所以建议任何情况下使用杜教筛都用哈希表记录计算过的值。

补一下反演过程:利用欧拉反演我们知道 dxφ(d)=x\sum_{d|x}\varphi(d)=x,还有一个冷知识是 i=1ni3=(i=1ni)2=n2(n+1)24\sum_{i=1}^ni^3=(\sum_{i=1}^ni)^2=\frac{n^2(n+1)^2}{4}

i=1nj=1nij(i,j)=i=1nj=1nijk(i,j)φ(k)=k=1nk2φ(k)i=1n/kij=1n/kj=k=1nk2φ(k)((n/k)(n/k+1)2)2\begin{aligned}&\sum_{i=1}^n\sum_{j=1}^nij(i,j)\\=&\sum_{i=1}^n\sum_{j=1}^nij\sum_{k|(i,j)}\varphi(k)\\=&\sum_{k=1}^nk^2\varphi(k)\sum_{i=1}^{n/k}i\sum_{j=1}^{n/k}j\\=&\sum_{k=1}^nk^2\varphi(k)\left(\frac{(n/k)(n/k+1)}{2}\right)^2\end{aligned}

到这一步已经能算了,你喜欢的话也可以接着用那个冷知识再化一步。

Powerful Number 筛

通常简记为 PN\text{PN} 筛,是杜教筛的一种扩展。

Powerful Number\text{Powerful Number}:每个质因子的幂次都 2\ge 2 的数,我喜欢把其构成的集合记作 PN\mathbb{PN}(懒得打)。

性质:PN[1,n]=O(n)|\mathbb{PN}\cap[1,n]|=\mathcal O(\sqrt n)

显然 x=a2b3    xPNx=a^2b^3\iff x\in\mathbb{PN},考虑把每个奇数次质因子扔三个到 bb 里,剩下的和偶数次的扔到 aa 里,枚举 aa 可得:

O(a=1n(na2)13)=O(1n(nx2)13dx)=O(n)\begin{aligned}&\mathcal O\left(\sum_{a=1}^{\sqrt n}\left(\frac n{a^2}\right)^{\frac 1 3}\right)\\&=\mathcal O\left(\int_1^{\sqrt n}\left(\frac n{x^2}\right)^{\frac 1 3}dx\right)\\&=\mathcal O(\sqrt n)\\\end{aligned}

求出 PN[1,n]\mathbb{PN}\cap[1,n] 只需要暴力搜索质因数组合即可。

设我们要求前缀和的积性函数是 f(x)f(x),我们构造两个积性(狄利克雷卷积关于积性函数是封闭的)函数 g,hg,h 满足 f=ghf=g*h,且满足以下条件:

  • pP,f(p)=g(p)\forall p\in\mathbb P,f(p)=g(p)

那么由于 pP,f(p)=g(p)h(1)+g(1)h(p)\forall p\in\mathbb P,f(p)=g(p)h(1)+g(1)h(p),可得 h(1)=1,h(p)=0h(1)=1,h(p)=0

由于 hh 是积性函数,所以只有在 xPNx\in\mathbb{PN}h(x)h(x) 有可能不为 00

F(x)=i=1xf(i),G(x)=i=1xg(i)F(x)=\sum_{i=1}^xf(i),G(x)=\sum_{i=1}^x g(i),则:

F(n)=i=1n(gh)(i)=ijng(j)h(i)=i=1nh(i)j=1[ni]g(i)=i[1,n]PNh(i)G([ni])\begin{aligned}F(n)&=\sum_{i=1}^n(g*h)(i)\\&=\sum_{ij\le n}g(j)h(i)\\&=\sum_{i=1}^nh(i)\sum_{j=1}^{[\frac n i]}g(i)\\&=\sum_{i\in[1,n]\cap\mathbb{PN}}h(i)G\left(\left[\frac n i\right]\right)\end{aligned}

放下 G([ni])G([\frac n i]) 不管,我们还需要求出 h(xPN)h(x\in\mathbb{PN})

由于积性函数,其实质就是要求 h(pk),pPh(p^k),p\in\mathbb P

外层枚举是 Θ(n)\Theta(\sqrt n) 的,里面的 GG 根据杜教筛特性只需求一次,Θ(n23)\Theta(n^{\frac 2 3}),我们就求出了这种积性函数的前缀和。

特别的,若 GG 容易计算,则该算法复杂度为 Θ(n)\Theta(\sqrt n)

GG 不容易计算时使用杜教筛,由于我们要用到的是其块筛,所以时间复杂度就是 Θ(n2/3)\Theta(n^{2/3})

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
总字数 231.7k 访客数 访问量