📜  Mobius函数|套装2(1)

📅  最后修改于: 2023-12-03 14:44:19.694000             🧑  作者: Mango

Mobius函数|套装2

简介

Mobius函数属于数论分析中的一类算术函数,用于描述自然数分解质因数后的奇偶性。若一个自然数$n$的质因数分解中有重复的质因数,则定为$0$;若无,则为$1$或$-1$。在本套装中,我们实现了关于Mobius函数的四个算法:积性函数、DP函数、杜教筛、整除分块。

功能简介

本套装包含以下功能:

Mobius积性函数

mobius_multiplicative函数实现了积性函数版本的Mobius函数。

from typing import List

def mobius_multiplicative(n: int) -> int:
    """
    Calculate Mobius function using multiplicative function.
    """
    mobius = 1
    p = 2
    while n > 1:
        if n % p == 0:
            n //= p
            if n % p == 0:
                return 0
            mobius = -mobius
        p += 1
    return mobius

该函数将$n$质因数分解,若有一个质数$p$的幂次$>1$,则返回$0$;否则返回$1$或$-1$。

Mobius DP函数

mobius_dp函数使用动态规划实现了计算前缀范围内的Mobius函数值。

def mobius_dp(n: int) -> List[int]:
    """
    Calculate Mobius function using DP.
    """
    mobius = [1] * (n + 1)
    for i in range(2, n + 1):
        if mobius[i] != 1:
            continue
        for j in range(i, n + 1, i):
            mobius[j] *= -1
            if j // i % i == 0:
                mobius[j] = 0
    return mobius

该函数使用了Mobius函数的前缀积性质,使用DP从小到大计算每个数的Mobius函数值。

Mobius杜教筛

mobius_du_jiaosai函数使用杜教筛实现了计算前缀范围内的Mobius函数值。

def mobius_du_jiaosai(n: int, prime: List[int]) -> List[int]:
    """
    Calculate Mobius function using Du Jiaosai method.
    """
    mobius = [1] * (n + 1)
    for p in prime:
        for j in range(p, n + 1, p):
            mobius[j] *= -1
        for j in range(p*p, n + 1, p*p):
            mobius[j] = 0
    return mobius

该函数使用了杜教筛,使用前$n$个质数筛出前缀范围内的Mobius函数值。

Mobius整除分块

mobius_divide_conquer函数使用整除分块实现了计算前缀范围内的Mobius函数值。

def mobius_divide_conquer(n: int, b: int = 500) -> List[int]:
    """
    Calculate Mobius function using divide-and-conquer.
    """
    mobius = [1] * (n + 1)
    for i in range(2, n + 1):
        if mobius[i] != 1:
            continue
        for j in range(i*i, min(n + 1, i*b), i*i):
            mobius[j] = 0
        for j in range(max(i*b, (n // i + 1)), n + 1):
            mobius[j] = mobius_multiplicative(j // i) * (-1)
    return mobius

该函数使用了整除分块,将$n$划分为大小为$b$的块,对于每个块$i$,使用筛法计算出$i$到$i+b$的Mobius函数值,再使用积性函数计算出$i+b$到$n$的Mobius函数值。

使用方法
mobius_multiplicative
mobius_multiplicative(n: int) -> int

输入一个正整数$n$,返回$n$的Mobius函数值。若$n$有一个质因数的幂次$>1$,则返回$0$;否则返回$1$或$-1$。

mobius_dp
mobius_dp(n: int) -> List[int]

输入一个正整数$n$,返回长度为$n+1$的列表,列表中第$i$个元素表示$1$到$i$的Mobius函数值。

mobius_du_jiaosai
mobius_du_jiaosai(n: int, prime: List[int]) -> List[int]

输入一个正整数$n$和一个不大于$n$的质数列表$prime$,返回长度为$n+1$的列表,列表中第$i$个元素表示$1$到$i$的Mobius函数值。

mobius_divide_conquer
mobius_divide_conquer(n: int, b: int = 500) -> List[int]

输入一个正整数$n$和一个正整数$b$(可选,默认值为$500$),返回长度为$n+1$的列表,列表中第$i$个元素表示$1$到$i$的Mobius函数值。