zoukankan      html  css  js  c++  java
  • 积性筛

    一些定义

    • 数论函数:定义域为正整数的函数。
    • 积性函数:满足(f(a)f(b)=f(ab) (gcd(a,b)=1))的数论函数。
    • 积性筛:在低于线性的时间内求出积性函数前缀和的奇妙算法。

    一些积性函数

    • (varphi(x)):欧拉函数。
    • (mu(x)):莫比乌斯函数。
    • (epsilon(x)):元函数。(epsilon(x)=delta_{x1})
    • (d(x)):约数函数。(d(x)=sum_{d|x}1)
    • (sigma(x)):约数和函数。(sigma(x)=sum_{d|x}d)
    • (I(x)):恒等函数。(I(x)=1)
    • (id(x)):单位函数。(id(x)=x)

    狄利克雷卷积

    • 两个数论函数(f(x),g(x))的狄利克雷卷积定义为:(f*g=sum_{d|n}f(d)g(frac nd))
    • 显然,狄利克雷卷积满足交换律、结合律、分配律。并且我们不难发现一个性质:两个积性函数的狄利克雷卷积依然是积性函数。

    杜教筛

    算法流程

    • (S(n)=sum_{i=1}^n f(i))。我们要求一个(S(n))
    • 设有另一个积性函数(g),并设(h=f*g),则有:

    [sum_{i=1}^nh(i)=sum_{i=1}^nsum_{d|i}f(d)g(frac id)=sum_{d=1}^ng(d)sum_{i=1}^{lfloorfrac nd floor}f(i)=sum_{d=1}^ng(d)S(lfloorfrac nd floor) ]

    • 因此,(g(1)S(n)=sum_{i=1}^nh(i)-sum_{d=2}^ng(d)S(lfloorfrac nd floor))
    • 由于(g)是积性函数,(g(1)=1),所以(S(n))就等于右式。

    • 对于(sum h(i)),我们要有一个快速求它的算法(一般要求时间不超(O(sqrt n)));而对于被减数,我们可以先分块,然后递归求解(S(lfloorfrac nd floor))。由于(lfloorfrac {lfloorfrac ab floor}c floor=lfloorfrac a{bc} floor),我们算过的(S(x))一定满足(x=lfloorfrac nd floor(din[1,n])),故可以用两个桶(一个是(≤sqrt n)的,一个是(>sqrt n)的,当然也可以合成一个桶)记忆化一下。
    • 空间复杂度显然(O(sqrt n))
    • 时间的话,可以发现(x=lfloorfrac nd floor(din[1,n]))只有(O(sqrt n))种取值,而且它们都是算过一次就不再算了(记忆化)。因此,(T(n)=sum_{i=1}^{sqrt n}O(sqrt i)+O(sqrt{lfloorfrac ni floor}))。可以求一个定积分,便知(T(n)=O(n^{frac 34}))
    • 如果先用线筛预处理出前(n^{frac 23})项,剩余部分的时间复杂度为(O(int_0^{n^{frac 13}}sqrt{frac nx}dx)=O(n^{frac 23}))

    简单例题

    T1
    • (S(n)=sum_{i=1}^nmu(i))
    • 我们知道(mu)有个性质:(mu*I=epsilon)。那么直接套公式便可得:(S(n)=1-sum_{d=2}^nS(lfloorfrac nd floor))
    T2
    • 定义(f(n)=nvarphi(n)),求(S(n)=sum_{i=1}^nf(i))
    • (h=f*id),可知(h(n)=sum_{d|n}nvarphi(d)=n^2)。则:(S(n)=frac{n(n+1)(2n+1)}6-sum_{d=2}^ndS(lfloorfrac nd floor))
    T3:51nod2026
    • 题目其实是要求((S(n)=sum_{i=1}^nf(i))^2)
    • 稍微推一下式子,(S(n)=sum_{i=1}^nsum_{d|i}dmu(d)=sum_{d=1}^ndmu(d)lfloorfrac nd floor)。后面(lfloorfrac nd floor)可以分块来处理,现在我们要处理的只是若干个(s(x)=sum_{d=1}^xdmu(d))而已(而且这些(x)也都是(n)整除某一个数得来)。
    • 依然让它卷上(id)(h(n)=sum_{d|n}nmu(d)=epsilon(n))。则:(s(n)=1-sum_{d=2}^ndS(lfloorfrac nd floor))
    #include <cmath>
    #include <cstdio>
    #define fo(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    
    const int M=1e5,N=2e5,mo=1e9+7;
    int n,k,s[N],S;
    bool v[N];
    
    int C(int x) {return x<=k?M+x:n/x;}
    int P(int&x,int y) {x=(1ll*x+y)%mo;}
    void gets(int x)
    {
    	v[C(x)]=s[C(x)]=1;
    	for(int i,l=2,r; l<=x; l=r+1)
    	{
    		r=x/(i=x/l);
    		if(!v[C(i)]) gets(i);
    		P(s[C(x)],mo-1ll*(l+r)*(r-l+1)/2%mo*s[C(i)]%mo);
    	}
    }
    
    int main()
    {
    	scanf("%d",&n), k=sqrt(n);
    	gets(n);
    	for(int i,l=1,r; l<=n; l=r+1)
    	{
    		r=n/(i=n/l);
    		P(S,1ll*i*(1ll*mo+s[C(r)]-s[C(l-1)])%mo);
    	}
    	printf("%lld",1ll*S*S%mo);
    }
    

    Min_25筛

    前言

    • 16年rzz在集训队论文里发明了个洲阁筛,它可以在(O(frac{n^{frac 34}}{log n}))的时间内筛出个性质较难发现的积性函数的前缀和。
    • 不过zzt觉得它又臭又长,于是在18年集训队论文里引进了Min_25发明的Min_25筛。
    • 据说是洲阁筛的精简版。

    算法简介

    • 首先我们须保证(f(p^c))(p)是质数)可以快速计算。我们要求(F(n)=sum_{i=1}^nf(i))
    • (p_k)为第(k)小的质数。设(lpf(n))(n)的最小质因数,(n=1)时其值为1;(F_k(n)=sum_{i=2}^n[p_k≤lpf(i)]f(i))。则可得:
      egin{aligned} F_{k}(n) &= sum_{i = 2}^{n} [p_{k} le operatorname{lpf}(i)] f(i) &= sum_{substack{k le i p_{i}^{2} le n}} sum_{substack{c ge 1 p_{i}^{c} le n}} fleft(p_{i}^{c} ight) ([c > 1] + F_{i + 1}left(n / p_{i}^{c} ight)) + sum_{substack{k le i p_{i} le n}} f(p_{i}) &= sum_{substack{k le i p_{i}^{2} le n}} sum_{substack{c ge 1 p_{i}^{c} le n}} fleft(p_{i}^{c} ight) ([c > 1] + F_{i + 1}left(n / p_{i}^{c} ight)) + F_{mathrm{prime}}(n) - F_{mathrm{prime}}(p_{k - 1}) &= sum_{substack{k le i p_{i}^{2} le n}} sum_{substack{c ge 1 p_{i}^{c + 1} le n}} left(fleft(p_{i}^{c} ight) F_{i + 1}left(n / p_{i}^{c} ight) + fleft(p_{i}^{c + 1} ight) ight) + F_{mathrm{prime}}(n) - F_{mathrm{prime}}(p_{k - 1}) end{aligned}

    • 现在考虑计算(F_{prime}(n)=sum_{2≤p≤n})
    • (G_k(n)=sum_{i=2}^n[p_k<lpf(i)lor isprime(i)]f(i)),即埃氏筛筛完k轮后剩下数的和,则显然(F_{prime}=G_{sqrt n})。记(G_0=sum_{i=2}^nf(i))
    • 转移即为: G_{k}(n) = G_{k - 1}(n) - left[p_{k}^{2} le n ight] g(p_{k}) (G_{k - 1}(n / p_{k}) - G_{k - 1}(p_{k - 1}))
  • 相关阅读:
    [LeetCode] 157. Read N Characters Given Read4 用Read4来读取N个字符
    [LeetCode] 158. Read N Characters Given Read4 II
    AndroidManifest.xml文件详解(activity)(一)
    Android中Bitmap、Drawable、byte[]转换
    图片和byte[]数组互转
    EditText 属性
    adb server didn't ack failed to start daemon
    PhoneGap 获得设备属性Demo
    PhoneGap 第一个程序
    android手机常用分辨率
  • 原文地址:https://www.cnblogs.com/Iking123/p/11593443.html
Copyright © 2011-2022 走看看