之前学杜教筛的时候感觉没有学的很明白,现在重新学习一遍。
杜教筛简介
何为杜教筛?
说直白一点就是在低于线性的时间内求出某个积性函数的前缀和。
假设现在我们有一个积性函数f(i),设S(i)=i∑j=1f(i)。
我们要求S(n),假设我们找到了另一个任意数论函数g(i) 。
那么可以很轻松地得到如下的推导:
n∑i=1(f∗g)(i)=n∑i=1∑d|ig(d)f(id)=n∑d=1g(d)n∑d|if(id)=n∑d=1g(d)⌊nd⌋∑i=1f(i)=n∑d=1g(d)S(⌊nd⌋)然后我们做进一步推导:
n∑i=1(f∗g)(i)=n∑d=1g(d)S(⌊nd⌋)=g(1)S(n)+n∑d=2g(d)S(⌊nd⌋)∴g(1)S(n)=n∑i=1(f∗g)(i)−n∑d=2g(d)S(⌊nd⌋)也就是说,如果我们能够找到一个积性函数g,并且我们能够快速计算(f∗g)的前缀和,g的前缀和,那么我们的问题就可以用我们最后得到的那个式子进行计算,具体来说就是可以用数论分块,然后最后一项进行递归处理。
例题
BZOJ 3944
题意
求$\sum\limits{i=1}^{n} \varphi(i)和\sum\limits{i=1}^{n} \mu(i)$。
n⩽231−1
题解
我们首先考虑n∑i=1φ(i)。
按照刚才那套理论,我们需要找到一个函数g,并且(g∗φ)和g的前缀和均能够容易求出。
我们不难想到,φ∗I=id,并且id和1的函数均可以很容易地求出。
所以不妨令g函数就是恒等函数I。
那么我们就有:
S(n)=n∑i=1i−n∑i=2S(⌊ni⌋)然后就可以前半部分用公式,后半部分数论分块+递归。
我们再来考虑n∑i=1μ(i)。
按照刚才那套理论,我们需要找到一个函数g,并且(g∗μ)和g的前缀和均能够容易求出。
我们不难想到μ∗1=ε。
那么我们不妨令g为恒等函数I。
于是我们带入得到:
S(n)=1−n∑i=2S(⌊ni⌋)直接数论分块+递归即可。
洛谷P3768 简单的数学题
题意
求$\sum\limits{i=1} ^{n}\sum\limits\limits {j=1} ^{n} ij*gcd(i,j)$
n⩽1010
题解
我们首先对原式进行反演。
Ans=n∑i=1n∑j=1ij∗gcd(i,j)=n∑i=1n∑j=1ij∑d|i,d|jφ(d)=n∑d=1φ(d)n∑i|dn∑j|dij=n∑d=1φ(d)d2⌊nd⌋∑i=1⌊nd⌋∑j=1ij=n∑d=1φ(d)d2(⌊nd⌋∑i=1i)2=n∑d=1φ(d)d2⌊nd⌋∑i=1i3现在的问题就是快速求出φ(d)d2的前缀和。
我们设f(i)=φ(i)∗i2,S(i)=i∑j=1f(j)。
现在我们要找到函数g,使得我们能够快速计算(f∗g)的前缀和,g的前缀和。
也就是说,我们需要能够快速求以下这个式子:
Ans=n∑i=1∑d|if(d)∗g(id)=n∑i=1∑d|iφ(d)d2∗g(id)我们不妨令g(i)=i2Ans=n∑i=1∑d|iφ(d)i2=n∑i=1i3所以我们只需要使g(i)=i2,然后继续使用刚才的刚才的方法就可以完成此题。
v1.5.2