由于不想再估了,所以把之前写的 copy 一遍,顺便复习一下。(捂脸)
整除分块
考虑这样一个问题,求:
因为题目要求的是向下取整,所以肯定会有一些相同的部分,对于这些相同的部分可以直接一起累加。
给定一个数(k),满足(lfloorfrac{n}{x} floor=lfloorfrac{n}{k} floor)相同的最大的(x)就是(lfloorfrac{n}{lfloorfrac{n}{k} floor} floor)。
于是代码大概是这样的:
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l);
ans+=(r-l+1)*(n/l);
}
时间复杂度:(O(sqrt{n}))
时间复杂度的证明:
(lfloorfrac{n}{a} floor)最多有(2sqrt{n})种取值。当(a<=sqrt{n})时,共有(sqrt{n})取值;当(a>sqrt{n})时,(lfloorfrac{n}{a} floor<sqrt{n}),也是共有(sqrt{n})种取值。每次都是将同一种取值的范围全部取完,所以复杂度就是(O(sqrt{n}))。
数论函数
在数论上,算术函数(或称数论函数)指定义域为正整数、陪域为复数的函数,每个算术函数都可视为复数的序列。-百度百科
默认下面讲到的都是数论函数。
函数的运算:
积性函数
如果对于任意的(gcd(n,m)=1),都满足(f(nm)=f(n)f(m)),我们就称这个函数是积性函数。
如果即使不满足(gcd(n,m)=1),也有(f(nm)=f(n)f(m)),那么就称这个函数是完全积性函数。
常见的积性函数:
常见的完全积性函数:
积性函数的一个性质:两个积性函数的狄利克雷卷积还是积性函数。
狄利克雷卷积
数论函数(f(n),g(n))的狄利克雷卷积是一个数论函数,定义为
简单记为:(t=f*g)
狄利克雷卷积满足的一些性质:
-
[ ext{交换律:}f*g=g*f ]
-
[ ext{结合律:}(f*g)*h=f*(g*h) ]
-
[ ext{分配律:}f*h+g*h=(f+g)*h ]
-
[(xf)*g=x(f*g) ]
-
[epsilon *f=f ]
-
[ ext{逆元:对于每一个}f(1) e 0 ext{的函数}f ext{都存在函数}g ext{使得}f*g=epsilon ]
对于性质六,考虑构造一个满足条件的(g):
由狄利克雷卷积的定义可以得到:
所以有:
和狄利克雷卷积相关的一些东西:
证明:
原式就是(sum_{dmid n}mu(d)=[n==1])
设(n=p_1^{k_1}p_2^{k_2}dots p_x^{k_x}(pin prime))
若(d)分解后其中的某个质因子的次数大于1,那么(mu(d)=0),我们只考虑(mu(d) e 0)的情况,相当于要证明:[inom{x}{0}-inom{x}{1}+inom{x}{2}-dots+(-1)^xinom{x}{x} ]当(n=1)时,(x=0),显然有(inom{0}{0}=1)
当(n e 1)时,有:[inom{x}{0}+inom{x}{2}+dots=sum_{i=1}^{x-1}inom{x-1}{i} ][inom{x}{1}+inom{x}{3}+dots=sum_{i=1}^{x-1}inom{x-1}{i} ]两式相减就是原式,所以原式等于0。
证明:
原式就是(sum_{dmid n}varphi(d)=n)
写出(n)个分数:[frac{1}{n},frac{2}{n},frac{3}{n},cdots,frac{n}{n} ]化简后,分数(frac{a}{d})存在当且仅当(gcd(a,d)=1,dmid n)。
所以分母为(d)的分数有(varphi(d))个。
由此我们可以得到(varphi)和(mu)的关系:
杜教筛
杜教筛可以以低于线性的时间复杂度来计算积性函数的前缀和。
求:(sum_{i=1}^nf(i))
我们要构造两个积性函数(h)和(g),使得(h=f*g)
设(S(n)=sum_{i=1}^nf(i))
(S(lfloorfrac{n}{d} floor))可以用整除分块,一般如果(h)的前缀和好求,那么就可以递归较快地求出(S)。
实现可以先筛出前一部分的函数值,然后递归求解答案,一般要用hash或者unordered_map记录(f(n))。
举例:求(sum_{i=1}^nmu(i))。
莫比乌斯反演
莫比乌斯反演定理:
证明如下:
其实还有更简便的证明:
另一种形式:
举例:求(sum_{i=1}^nsum_{j=1}^mgcd(i,j))。
答案就是:
(varphi(d))可以直接线性筛得到,如果只是单组询问,可以直接(O(n))做,否则把后面部分做个前缀和,然后就可以整除分块做了。
附整除分块的代码:
int mx=min(n,m),ans=0;
for(int l=1,r;l<=mx;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=sum[r]-sum[l-1];
}
模板题:
不那么模板的题目:
-
P1829 [国家集训队]Crash的数字表格 / JZPTAB(注:此题并没有用到莫比乌斯反演,而是用到了莫比乌斯函数的一个性质)
-
P3768 简单的数学题(注:此题要用杜教筛)
可能可以做的题目: