数论学习笔记1之积性函数与线性筛求积性函数

一、积性函数

1.1 定义

积性函数又称为乘性函数,在数论中有很多这样的函数。
定义在所有正整数上的函数称为算术函数。

而 对 于 任 意 算 术 函 数 f 如 果 满 足 任 意 两 个 互 质 的 正 整 数 n 和 m 均 有 f ( m n ) = f ( m ) f ( n ) , 则 称 f 为 积 性 函 数 , 或 者 : f 为 积 性 函 数 当 且 仅 当 g c d ( m , n ) = 1 且 f ( m n ) = f ( m ) f ( n ) 此 外 , 给 出 完 全 积 性 函 数 的 定 义 : 对 于 任 意 正 整 数 n , m , 均 有 f ( m n ) = f ( m ) f ( n ) , 则 称 f 为 完 全 积 性 函 数 \begin{aligned} &而对于任意算术函数f如果满足任意两个互质的正整数n和m\\ &均有f(mn) = f(m)f(n),则称f为积性函数,或者:\\ &f为积性函数当且仅当gcd(m,n)=1且f(mn) = f(m)f(n)\\ &\\ &此外,给出完全积性函数的定义:\\ &对于任意正整数n,m,均有f(mn) = f(m)f(n),则称f为完全积性函数 \end{aligned} fnmf(mn)=f(m)f(n)ffgcd(m,n)=1f(mn)=f(m)f(n)n,mf(mn)=f(m)f(n)f

1.2 定理

定理1:
如 果 f 是 积 性 函 数 , 对 于 n 有 算 数 基 本 定 理 : n = p 1 a 1 p 2 a 2 . . . p k a k , 再 由 积 性 函 数 性 质 : 则 f ( n ) = f ( p 1 a 1 p 2 a 2 . . . p k a k ) = f ( p 1 a 1 ) f ( p 2 a 2 ) . . . f ( p k a k ) \begin{aligned} &如果f是积性函数,对于n有算数基本定理:\\ &n = p_1^{a_1}p_2^{a_2}...p_k^{a_k},再由积性函数性质:\\ &则f(n) = f(p_1^{a_1}p_2^{a_2}...p_k^{a_k})\\ &=f({p_1}^{a_1})f(p_2^{a_2})...f(p_k^{a_k}) \end{aligned} fn:n=p1a1p2a2...pkak,f(n)=f(p1a1p2a2...pkak)=f(p1a1)f(p2a2)...f(pkak)

1.3 常见的积性函数

i d , d , φ , δ , I , μ , ϵ id ,d,\varphi,\delta,I,\mu,\epsilon id,d,φ,δ,I,μ,ϵ
i d : 单 位 函 数 ( 恒 等 函 数 ) , 定 义 为 i d ( n ) = n ( 完 全 积 性 ) d : 除 数 函 数 ( 约 数 个 数 函 数 ) , d ( i ) = ∑ d ∣ N 1 φ : 1 − n 中 与 n 互 质 的 数 的 个 数 , φ ( i ) = i ⋅ ∏ i = 1 p k ( 1 − 1 p i ) δ : 约 数 和 函 数 , δ ( i ) = ∑ d ∣ N d I : 不 变 函 数 : I ( i ) = 1 μ : 莫 比 乌 斯 函 数 : 对 于 μ ( i ) : 当 i = 1 时 , μ ( i ) = 1 当 i 分 解 质 因 数 后 , 所 有 质 因 数 的 指 数 只 要 有 1 个 ≥ 2 , 则 μ ( i ) = 0 否 则 , μ ( i ) = ( − 1 ) k , k 即 是 质 因 数 的 个 数 ϵ : 单 位 元 函 数 , ϵ ( i ) = [ n = 1 ] , [ n = 1 ] 表 示 只 有 当 n = 1 时 , 该 值 为 1 , 其 他 n 的 取 值 均 使 [ n = 1 ] = 0 [ n = 1 ] 这 种 属 于 真 值 函 数 , 如 果 说 括 号 内 条 件 成 立 , 那 么 才 会 对 和 式 有 贡 献 常 见 的 还 有 [ g c d ( i , j ) = 1 ] \begin{aligned} &id:单位函数(恒等函数),定义为 i d ( n ) =n(完全积性)\\ &d:除数函数(约数个数函数),d(i) = \sum_{d|N}1\\ &\varphi:1-n中与n互质的数的个数,\varphi(i) =i\cdot \prod_{i=1}^{p_k}(1-\frac 1 {p_i})\\ &\delta:约数和函数,\delta(i) = \sum_{d|N}d\\ &I:不变函数:I(i) = 1\\ &\mu:莫比乌斯函数:对于\mu(i):\\ &当i=1时,\mu(i) = 1\\&当i分解质因数后,所有质因数的指数只要有1个≥2,则\mu(i) = 0\\ &否则,\mu(i) = (-1)^k,k即是质因数的个数\\ &\epsilon:单位元函数,\epsilon(i) = [n=1],[n=1]表示只有当n=1时,该值为1,其他n的取值均使[n=1] = 0\\ &[n=1]这种属于真值函数,如果说括号内条件成立,那么才会对和式有贡献\\ &常见的还有[gcd(i,j)=1] \end{aligned} id:id(n)=nd:)d(i)=dN1φ:1nn,φ(i)=ii=1pk(1pi1)δ:,δ(i)=dNdI::I(i)=1μ:μ(i):i=1μ(i)=1i12,μ(i)=0,μ(i)=(1)k,kϵ:ϵ(i)=[n=1],[n=1]n=1,1n使[n=1]=0[n=1][gcd(i,j)=1]

1.4 狄利克雷卷积

这 里 给 出 普 通 卷 积 的 定 义 和 狄 利 克 雷 卷 积 的 定 义 读 者 观 察 即 可 清 楚 他 们 的 区 别 ( f ∗ g ) ( n ) 表 示 f 卷 积 g 的 第 n 项 普 通 卷 积 : ( f ∗ g ) ( n ) = ∑ i + j = n f ( i ) g ( n − i ) 狄 利 克 雷 卷 积 ( f ∗ g ) ( n ) = ∑ i ⋅ j = n f ( i ) g ( n i ) 狄 利 克 雷 卷 积 的 常 见 形 式 : ( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) \begin{aligned} &这里给出普通卷积的定义和狄利克雷卷积的定义\\ &读者观察即可清楚他们的区别\\ &(f*g)(n)表示f卷积g的第n项\\ &\\ &普通卷积:(f*g)(n) = \sum_{i+j=n}f(i)g(n-i)\\ &狄利克雷卷积(f*g)(n) = \sum_{i\cdot j=n}f(i)g(\frac n i)\\ &狄利克雷卷积的常见形式: \\ &(f*g)(n) = \sum_{d|n}f(d)g(\frac n d) \end{aligned} (fg)(n)fgn(fg)(n)=i+j=nf(i)g(ni)(fg)(n)=ij=nf(i)g(in)(fg)(n)=dnf(d)g(dn)

1.4.1 狄利克雷卷积的性质

1.交换律
( f ∗ g ) ( n ) = ( g ∗ f ) ( n ) (f*g)(n) = (g*f)(n) (fg)(n)=(gf)(n)
2.结合律
( f ∗ g ∗ h ) ( n ) = ( f ∗ ( g ∗ h ) ) ( n ) (f*g*h)(n) = (f*(g*h))(n) (fgh)(n)=(f(gh))(n)
3. 分配律: f ∗ ( g + h ) = f ∗ g + f ∗ h f*(g+h) = f*g+f*h f(g+h)=fg+fh
4. 卷积单位元: f ∗ ϵ = f 类 似 a ⋅ 1 = a f*\epsilon = f\\类似a\cdot 1 = a fϵ=fa1=a
5. 逆元: 如 果 f ∗ g = ϵ , 则 g 是 f 的 逆 元 如果f*g = \epsilon,则g是f的逆元 fg=ϵ,gf
6. 若 函 数 f , g 为 积 性 函 数 , 则 f ∗ g 也 为 积 性 函 数 若函数f , g 为积性函数,则f ∗ g也为积性函数 f,gfg

1.4.2 常见积性函数的卷积

(1) μ ∗ I = ϵ ∗ I = I ∗ I = d \mu*I = \epsilon*I = I*I = d μI=ϵI=II=d
(2) φ ∗ I = i d ∗ I = δ \varphi*I = id*I = \delta φI=idI=δ
(3) i d k ∗ I = δ k id^k * I = \delta^k idkI=δk
或者记
在这里插入图片描述

1.4.5 狄利克雷卷积的代码实现

//f*g O(nlogn)
void Dirichlet(ll *f, ll *g)
{
	int h[N] = {0};
	for(int i = 1; i <= n; ++ i) {
		for(int j = i; j <= n; j += i) {
			h[j] = (h[j] + f[i] * g[j / i]) % mod;
		}
	}
	for(int i = 1; i <= n; ++ i) 
		f[i] = h[i]; 
}  

二、线性筛求积性函数

2.1 前置知识

前言:线性筛积性函数的四个常见积性函数的筛法可以反复揣摩

线性筛:在O(n)时间复杂度内筛素数或者积性函数的东西。
任意积性函数均可以线性筛。
线性筛求积性函数一般就预处理N=1e7的数据,如果N=1e9就会超时了,考虑使用杜教筛,
但是依然要用线性筛预处理5e6左右的数据,这样能够加快杜教筛的速度。

2.2 线性筛素数

保证每个数只会被它的最小质因子给筛掉:

code:

void get_primes()
{
    for(int i = 2;i<=n;i++)
    {
        if(!st[i])
        {
            primes[cnt++] = i;
        }
        for(int j = 0;primes[j]<=n/i;j++)
        {
            st[primes[j]*i] = true;
            if(i%primes[j]==0) break;
        }
    }
}

2.3 线性筛欧拉函数

const int N = 1e7+10;
bool st[N];
typedef long long ll;
ll primes[N],cnt,phi[N];
int n;
void get_phi(int n)
{
    phi[1] = 1;
    for(int i = 2;i<=n;i++)
    {
        if(!st[i])
        {
            phi[i] = i-1;
            primes[cnt++] = i;
        }
        for(int j = 0;j<cnt&&i*primes[j]<=n;j++)
        {
            st[i*primes[j]] = true;
            if(i%primes[j]==0)
            {
                phi[i*primes[j]] = phi[i]*primes[j];
                break;
            }
            else
            {
                phi[i*primes[j]] = phi[i]*phi[primes[j]];
            }
        }
    }
}

2.4 线性筛莫比乌斯函数

const int N = 1e7+10;
bool st[N];
typedef long long ll;
int primes[N],cnt,mu[N];
int n;
void get_mu(int n)
{
    mu[1] = 1;
    for(int i = 2;i<=n;i++)
    {
        if(!st[i])
        {
            mu[i] = -1;
            primes[cnt++] = i;
        }
        for(int j = 0;j<cnt&&i*primes[j]<=n;j++)
        {
            st[i*primes[j]] = true;
            if(i%primes[j]==0)
            {
                mu[i*primes[j]] = 0;
                break;
            }
            else
            {
                mu[i*primes[j]] = mu[i]*mu[primes[j]];
            }
        }
    }
}

2.5 线性筛约数个数函数

const int N = 1e7+10;
bool st[N];
typedef long long ll;
ll primes[N],cnt,d[N],deg[N];
int n;
void get_d(int n)
{
    d[1] = 1,deg[1] = 1;
    for(int i = 2;i<=n;i++)
    {
        if(!st[i])
        {
            d[i] = 1+1,deg[i] = 1+1;
            primes[cnt++] = i;
        }
        for(int j = 0;j<cnt&&i*primes[j]<=n;j++)
        {
            st[i*primes[j]] = true;
            if(i%primes[j]==0)
            {
                d[i*primes[j]] = d[i]/deg[i]*(deg[i]+1);
                deg[i*primes[j]] = deg[i]+1;
                break;
            }
            else
            {
                d[i*primes[j]] = d[i]*2;
                deg[i*primes[j]] = 1+1;
            }
        }
    }
}

2.6 线性筛约数和函数

const int N = 1e7+10;
bool st[N];
typedef long long ll;
ll primes[N],cnt,delta[N],deg[N];
int n;
void get_delta(int n)
{
    delta[1] = 1,deg[1] = 1;
    for(int i = 2;i<=n;i++)
    {
        if(!st[i])
        {
            delta[i] = 1+i,deg[i] = 1+i;
            primes[cnt++] = i;
        }
        for(int j = 0;j<cnt&&i*primes[j]<=n;j++)
        {
            st[i*primes[j]] = true;
            if(i%primes[j]==0)
            {
                delta[i*primes[j]] = delta[i]*primes[j]+delta[i]/deg[i];
                deg[i*primes[j]] = deg[i]*primes[j]+1;
                break;
            }
            else
            {
                delta[i*primes[j]] = delta[i]*(1+primes[j]);
                deg[i*primes[j]] = 1+primes[j];
            }
        }
    }
}

2.7 线性筛一般积性函数

筛常见积性函数和筛一般积性函数的方式是一样的:这里尽量给出一般积性函数的线性筛法与模板。

1. 先 求 出 f ( 1 ) \begin{aligned} &1.先求出f(1)\\ \end{aligned} 1.f(1)

类似mu[1] = 1,phi[1] = 1,d[1] = 1,delta[1] = 1,f(1)是很好求的

2. 初 始 化 f ( p ) ( p 是 质 数 ) \begin{aligned} &2.初始化f(p)(p是质数)\\ \end{aligned} 2.f(p)(p)

for(int i = 2;i<=n;i++)
{
	if(!st[i])
	{
		//说明i是质数
		primes[cnt++] = i;
		f[i] = ?//根据积性函数不同而不同
	}
}

3. 在 筛 的 时 候 , 我 们 知 道 p r i m e s [ j ] 一 定 是 i ∗ p r i m e s [ j ] 的 最 小 质 因 子 , 然 后 对 于 i 有 算 数 基 本 定 理 得 到 p 1 a 1 p 2 a 2 . . . p k a k 易 有 两 种 情 况 : [ 1 ] p r i m e s [ j ] = p 1 即 ( i % p r i m e s [ j ] = = 0 ) [ 2 ] p r i m e s [ j ] < p 1 即 ( i % p r i m e s [ j ] ! = 0 ) ( 1 ) 对 于 第 一 种 情 况 , 显 然 i ∗ p r i m e s [ j ] 的 质 因 子 和 i 的 质 因 子 是 一 样 的 只 有 最 小 质 因 子 的 指 数 比 i 的 多 1 , 即 p 1 ( i ⋅ p r i m e s [ j ] ) = p 1 ( i ) + 1 ( 2 ) 对 于 第 二 种 情 况 , 显 然 p r i m e s [ j ] < p 1 , 故 p r i m e s [ j ] 一 定 是 与 i 互 质 的 不 妨 设 要 求 的 积 性 函 数 为 f , 则 f ( i ⋅ p r i m e s [ j ] ) = f ( i ) ⋅ f ( p r i m e s [ j ] ) ( 3 ) 第 一 种 情 况 里 f ( i ⋅ p r i m e s [ j ] ) 怎 么 求 呢 ? 这 就 要 引 入 线 性 筛 求 约 数 个 数 函 数 和 求 约 数 和 函 数 里 d e g 数 组 的 作 用 , 例 如 约 数 个 数 函 数 d , 易 有 d ( i ) = ( a 1 + 1 ) ( a 2 + 1 ) . . . ( a k + 1 ) 那 么 d ( i ∗ p r i m e s [ j ] ) = ( a 1 + 1 + 1 ) ( a 2 + 1 ) . . . ( a k + 1 ) 对 于 约 数 个 数 函 数 有 d e g [ i ] 表 示 最 小 质 因 数 的 指 数 + 1 , 即 d e g [ i ] = ( a 1 + 1 ) 那 么 d ( i ∗ p r i m e s [ j ] ) 就 好 求 了 , 首 先 i % p r i m e s [ j ] = = 0 使 得 d e g [ i ∗ p r i m e s [ j ] ] = d e g [ i ] + 1 再 考 虑 d [ i ∗ p r i m e s [ j ] ] = d [ i ] / d e g [ i ] ∗ d e g [ i ∗ p r i m e s [ j ] ] ; 建 议 读 者 在 纸 上 演 算 一 下 , 就 很 明 了 了 。 \begin{aligned} &3.在筛的时候,我们知道primes[j]一定是i*primes[j]的最小质因子,\\&然后对于i有算数基本定理得到p_1^{a_1}p_2^{a_2}...p_k^{a_k}\\&易有两种情况:\\ &[1]\quad primes[j]=p_1即(i\%primes[j]==0)\\ &[2]\quad primes[j]<p_1即(i\%primes[j]!=0)\\ &(1)对于第一种情况,显然i*primes[j]的质因子和i的质因子是一样的\\ &只有最小质因子的指数比i的多1,即\\ &{p_1}_{(i\cdot primes[j])} = {p_1}_{(i)}+1\\ &(2) 对于第二种情况,显然primes[j]<p_1,故primes[j]一定是与i互质的\\ &不妨设要求的积性函数为f,则f(i\cdot primes[j]) = f(i)\cdot f(primes[j])\\ &(3) 第一种情况里f(i\cdot primes[j])怎么求呢?\\ &这就要引入线性筛求约数个数函数和求约数和函数里\\&deg数组的作用,例如约数个数函数d,\\ &易有d(i) = (a_1+1)(a_2+1)...(a_k+1)\\ &那么d(i*primes[j]) = (a_1+1+1)(a_2+1)...(a_k+1)\\ &对于约数个数函数有deg[i] 表示最小质因数的指数+1,即deg[i] = (a_1+1)\\ &那么d(i*primes[j])就好求了,首先i\%primes[j]==0使得\\ &deg[i*primes[j]] = deg[i]+1\\ &再考虑d[i*primes[j]] = d[i]/deg[i]*deg[i*primes[j]]; \\&建议读者在纸上演算一下,就很明了了。 \end{aligned} 3.primes[j]iprimes[j],ip1a1p2a2...pkak[1]primes[j]=p1(i%primes[j]==0)[2]primes[j]<p1(i%primes[j]!=0)(1)iprimes[j]ii1p1(iprimes[j])=p1(i)+1(2)primes[j]<p1,primes[j]if,f(iprimes[j])=f(i)f(primes[j])(3)f(iprimes[j])线degdd(i)=(a1+1)(a2+1)...(ak+1)d(iprimes[j])=(a1+1+1)(a2+1)...(ak+1)deg[i]+1deg[i]=(a1+1)d(iprimes[j]),i%primes[j]==0使deg[iprimes[j]]=deg[i]+1d[iprimes[j]]=d[i]/deg[i]deg[iprimes[j]];

2.7.1 模板

一般地,可以写出线性筛一般积性函数的模板~

const int N = 1e7+10;
bool st[N];
typedef long long ll;
ll primes[N],cnt,f[N],f_deg[N];
//f_deg即是存放和最小质因子相关的一项
//在约数个数函数里f_deg = (a1+1)
//在约数和函数里f_deg = 1+p0^1+p0^2+...p0^n
int n;
void get_f(int n)
{
    f[1] = ?,f_deg[1] = ?;
    for(int i = 2;i<=n;i++)
    {
        if(!st[i])
        {
            f[i] = ?;f_deg[i] = ?;
            primes[cnt++] = i;
        }
        for(int j = 0;j<cnt&&i*primes[j]<=n;j++)
        {
            st[i*primes[j]] = true;
            if(i%primes[j]==0)
            {
                f[i*primes[j]] = ?;
                f_deg[i*primes[j]] = ?
                break;
            }
            else
            {
                f[i*primes[j]] = f[i]*f[primes[j]];//由积性函数性质
                f_deg[i*primes[j]] = ?;
            }
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值