积性函数筛法

积性函数筛法

很多常用的数论函数都是积性函数,而在题目中,我们常常需要线性(甚至更高)的筛法。

对于积性函数,我们可以在筛素数的基础上稍加修改,即可完成线性筛。

首先,注意到积性函数的特点:
\[
f(xy)=f(x)\times f(y)
\]
而可以线性筛的积性函数,需要知道以下两个式子的快速求法:
\[
f(p)=?\quad f(p^k)=?\\p\in prime
\]
其中, \(f(p)\) 大多是直接定义,\(f(p^k)\) 大多是递归定义。

我们来回忆一下素数筛的过程:

inp[0]=inp[1]=1;
for(int i=2;i<=n;i++){
    if(!inp[i]){
        prime[++tot]=i;
    }
    for(int j=1;j<=tot && i*prime[j]<=n;j++){
        int tp=prime[j]*i;
        inp[tp]=1;
        if(i%prime[j]==0){
            break;
        }
    }
}

在线性筛素数的基础上,我们可以进行线性筛的修改。

首先,对于判定的质数 \(p\) ,可以直接给出定义的值。

之后,对于 \(i\%p\neq0\) ,由于 \(i\) 和 \(p\) 互质,可以直接用积性函数性质推得。

然后,对于 \(i\%p == 0\) :

  • 即 \(i\) 内的最小素因子是 \(p\) ,此刻可以将 \(i\) 内的素因子都除掉,然后就可以用积性函数的性质来递推了。为此,我们要记录一个最小质因子的幂次 \(low_i\) 。

    那么递推式就可以表示为:\(f(i\times p)=f(i/low_i)\times f(low_i\times p)\) 。

  • 此处还有一个特殊的判定,当 \(i==low_i\) 时,上式相当于没推,所以我们要用 \(f(p^k)\) 的递推来计算。

那么代码如下:

inp[0]=inp[1]=1;
f[1]=1;
for(int i=2;i<=n;i++){
    if(!inp[i]){
        prime[++tot]=i;
        f[i]=对质数的定义式;
        low[i]=i;
    }
    for(int j=1;j<=tot && i*prime[j]<=n;j++){
        int tp=prime[j]*i;
        inp[tp]=1;
        if(i%prime[j]==0){
            if(i!=low[i])
                f[tp]=f[i/low[i]]*f[low[i]*prime[j]];
            else
                f[tp]=对p的次幂的定义式;
            low[tp]=low[i]*prime[j];
            break;
        }
        f[tp]=f[i]*f[prime[j]];
        low[tp]=prime[j];
    }
}

缺点很明显,比较耗空间。(但是题目会给够的

当需要线性筛很多个积性函数时,可以同时进行。

这种基于素数筛的线性筛法,有时不止对积性函数有用,对于一些和素数有关的函数也可以筛出,具体在我写的莫比乌斯反演中有例子。



\(\frak by\;thorn\_\)

原文地址:https://www.cnblogs.com/thornblog/p/12358432.html

时间: 2024-10-12 15:13:59

积性函数筛法的相关文章

读贾志鹏《线性筛法与积性函数》笔记

1.欧拉筛法在线性时间内求素数以及欧拉函数 代码: 1 procedure get; 2 var i,j,k:longint; 3 begin 4 tot:=0; 5 fillchar(check,sizeof(check),false); 6 for i:=2 to n do 7 begin 8 if not(check[i]) then 9 begin 10 inc(tot); 11 p[tot]:=i; 12 fai[i]:=i-1; 13 end; 14 for j:=1 to tot

积性函数求和:筛法DP、洲阁筛

如果定义在正整数集上的函数 $f(n)$ 满足对于任意一对互素正整数 $n, m$ 都有 $f(n)f(m)=f(nm)$, 那么 $f$ 就叫做积性函数. 积性函数又可以表示为,假设 $n$ 的素因子分解式为 $n=\prod_{i=1}^mp_i^{c_i}$, 那么 $f(n)=\prod_{i=1}^mg(p_i, c_i)$. 本文讨论的函数满足:$g(p, c)$ 能够快速求单点值,且 $g(x, 1)$ 是关于 $x$ 的低次多项式. 积性函数求和,就是要求出 $\sum_{n=1

常用积性函数的线性筛法整理

简单整理推导加代码,留复习用. 线性筛素数 最简单也最基础,直接看代码就好了\(--\) code: void Euler_Phi_Prime(int n) { is_prime[1] = true; for (int i = 2; i <= n; i++) { if (!is_prime[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { is_prime[i * pri

浅谈一类积性函数的前缀和(转载)

本文转自:http://blog.csdn.net/skywalkert/article/details/50500009 另外,莫比乌斯反演和杜教筛其他可转到 http://blog.leanote.com/post/totziens/%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%8F%8D%E6%BC%94 写在前面 笔者在刷题过程中遇到一些求积性函数前缀和的问题,其中有一类问题需要在低于线性时间复杂度的算法,今天就来浅析一下这类问题的求解方法,当作以后讲课

POJ2480 Longge&#39;s problem 欧拉函数的应用 &amp;&amp; 积性函数

题意很简单,求sum(gcd(i,n))   1<=i<=n; 这题看到后第一反应并没有里用积性函数的性质,不过也可以做,欣慰的是我反应还是比较快的 设f(n)=gcd(1,n)+gcd(2,n)+....+gcd(n-1,n) + gcd(n,n), 用g(n,i)表示满足 gcd(x,n)=i的 x的个数 (x小于n),则 f(n)=sum{i*g(n,i)}; 同时又利用 扩展欧几里德的性质  gcd(x,n)=i  的充要条件是 gcd(x/i,n/i)==1,所以 满足 x/i的解有

HDU 4002 Find the maximum (欧拉函数-积性函数的性质(2011年大连赛区网络赛第二题)

[题目链接]:click here~~ [题目大意]: 给出一个整数n,求一个数x,x在1到n之间,并且x/φ(x)最大(其中φ(x)为x的欧拉函数). [思路]: 由欧拉函数为积性函数,即:如果 则有: 且: 则有: 要使f(x)最大,须使x含尽量多的不同素数因子. 代码: /* * Problem: HDU No.4002 * Running time: 1700MS * Complier: java * Author: javaherongwei * Create Time: 0:08 2

线性筛及其扩展-积性函数

线性筛 埃氏筛 对于每个数x,枚举其倍数,将kx筛去. 在埃氏筛过程中,每个数都会被筛掉多次,且对于每个数x,枚举其倍数的次数为\(\frac{n}{x}\) 故埃氏筛的时间复杂度为\(\sum_{i=1}^{n}\)\(\frac{n}{i}\)=n\(\sum_{i=1}^{n}\)\(\frac{1}{i}\)=\(n ln(n)\) 欧拉筛 在埃氏筛中,每个数会被筛掉多次,想要进一步下降复杂度,我们要求每个数只会被筛一次. 要想将多种筛去x的方法固定(唯一).我们就要采用一种方法-"最小

HDU2879 HeHe 数论积性函数

题目名字有点搓,做题时没做出来,学长他们做出了,发现跟网上题解的思路没太大区别,网上所有题解的分析也都转自同一个地方,看样子这道题目不是那么好想的,没办法按照解析画了半天,计算器按了半天,理解了,自己敲出来了,觉得值得留念,打算再刷几道这样的 转自:http://blog.csdn.net/kksleric/article/details/8096914 定义:对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数.若对于某积

常见积性函数(转自百科)

前面做hdu1452 用过积性函数这个东西...刚才遇到又不会了.所以弄一点资料提醒一下自己 在非数论的领域,积性函数指所有对于任何a,b都有性质f(ab)=f(a)f(b)的函数. 在数论中的积性函数:对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数. 若对于某积性函数 f(n),就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性的.[1] s(6)=s(2)*s(3)=3*4=12; s(20)=