Math
数论
素数筛
从欧拉筛的角度来看,
考虑 [1,n] 内的数,
所有大于 n 的合数一定会被某个小于等于 n 的质数(最小的质因子一定小于等于 n,如果最小的质因子大于 n,要么他本身是一个质数,否则 p1p2>n⋅n=n 矛盾)筛掉.
所以当 n 很大时,可以只筛出 n 内的质数,用这些质数去(分段)筛大于 n 的那些数.
关于 gcd
容斥
如果遇到这样一类求和
T=A⊆S∑(a1,a2,…,an,k1,k2,…,km)⋅f(A)
其中 ai 是集合 A 里的元素,kj 是额外需要求gcd
的元素. 记 K=k1k2⋯km.
可以枚举 gcd
,转换为
T=d∣K∑(d⋅A⊆S∑[d=(a1,a2,…,an,k1,k2,…,km)]⋅f(A))
一般 f(A) 仅与集合 A 的大小有关,即
f(A)=h(∣A∣)
则有
T=d∣K∑⎝⎛d⋅l=1∑∣S∣h(l)A⊆S且∣A∣=l∑[d=(a1,a2,…,an,k1,k2,…,km)]⎠⎞
遍历集合 S 的每个数的因子,统计出因子 d 的出现次数为 cd,
那么大小为 l、gcd
至少为 d 的集合的个数为
g(d,l)=(lcd)
记
ϕ(d)=l=1∑min{cd,∣S∣}h(l)g(d,l)
则gcd
为 d 的集合的贡献为
Φ(d)=ϕ(d)−t∣(K/d)∑Φ(t)
容斥一波就可以搞出来了
T=d∣K∑d⋅Φ(d)
一些常见的 h(l),一般 cd≤∣S∣:
- h(l)=l, ϕ(d)=∑l=1cdl(lcd)=cd⋅2cd−1−1
- h(l)=λl, ϕ(d)=∑l=1cdλl(lcd)=(1+λ)cd−1