• 「从零开始的莫比乌斯反演」1. 线性筛&数论分块


    莫比乌斯反演在竞赛中属于数论的内容。虽然说,本系列是想写面向Beginner的教程,但是莫比乌斯反演在数论中并不是很基础的内容,你仍然需要有一定的数论知识的基础。

    PS:以下代码都是写博客的时候现场手打的,所以。。。

    你需要掌握

    • 取模和整除运算的相关知识
    • 质数筛法
    • 数论分块
    • 欧拉函数(可选,最好掌握)

    本文只讲数论分块并给出线性筛法的模版。其他内容请自行搜索学习。

    线性筛

    这里给出线性素数筛:

    int prime[maxn], numprime, isprime[maxn];	// isprime[i] == 0:i是素数,反之则不是。prime用来存素数
    void make_prime(const int &up_bound) {
        // 从0筛到up_bound,不包含up_bound
        isprime[0] = isprime[1] = 1;
        for (int i = 2; i < up_bound; i++) {
            if (!isprime[i]) prime[numprime++] = i;	// i是素数,放到prime数组里
            for (int j = 0; j < numprime && i * prime[j] < up_bound; j++) {
                isprime[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
    }
    

    数论函数多半与素数有关。所有的积性函数都可以在线性时间内借助素数筛筛出来(这里不理解没关系,后面还会说)。

    数论分块

    例题

    求:

    [sumlimits_{i=1}^{k}leftlfloor dfrac{n}{i} ight floor ]

    如果告诉你,(1 leq k leq n leq 10^6),那么,你可以直接枚举。那,如果告诉你,(1 leq k leq n leq 10^{12})呢?

    解法

    这就要用到数论分块了。数论分块能把复杂度降到(O(sqrt{n}))。原理如下:

    我们看几个整数除法的例子:

    (leftlfloor dfrac{10}{4} ight floor = 2, leftlfloor dfrac{10}{5} ight floor = 2, leftlfloor dfrac{10}{6} ight floor = 1, leftlfloor dfrac{10}{7} ight floor = 1 cdots)

    容易发现,总是有这么一段,它们做除法的结果是一样的。比如从(4)(5),除法的结果总是(2);从(6)(10),除法的结果总是(1)

    它在图上表示出来是这样的:

    (绘图软件是Geogebra)

    如果我们能把它相等的这一段,直接用乘法求出来,显然会比挨个做加法要快不少。那么,我们如何确定某一段的左右边界呢?

    结论

    先说结论,最后再说证明。结论很漂亮,但是证明很蛋疼。

    (x = leftlfloor dfrac{n}{l} ight floor)的右边界是(leftlfloor dfrac{n}{lfloor frac{n}{l} floor} ight floor)

    也就是说,对于(n)来说,如果(leftlfloor dfrac{n}{l} ight floor = x),那么令(r = leftlfloor dfrac{n}{lfloor frac{n}{l} floor} ight floor),则(leftlfloor dfrac{n}{r} ight floor)也等于(x)。且(r)(leftlfloor dfrac{n}{i} ight floor = x)的右边界,(leftlfloor dfrac{n}{r + 1} ight floor)就不等于(x)了。

    那么,这一段的求和就是(left(leftlfloor dfrac{n}{lfloor frac{n}{l} floor} ight floor - l + 1 ight) imes leftlfloor dfrac{n}{l} ight floor)

    上面提到的例题,代码如下:

    for (int l = 1, r; l <= k; l = r + 1) {
        r = min(n / (n / l), k);	// 注意不能超出k
        ans += (r - l + 1) * (n / l);
    }
    

    十分简洁。

    在不同的地方应用数论分块写起来会有点不同,不过总体上大同小异。

    稍微难一点的例题

    如果我们要求(sumlimits_{i=1}^{k}leftlfloor dfrac{n}{i} ight floor leftlfloor dfrac{m}{i} ight floor)呢?

    这里会遇到的一个问题就是(leftlfloor dfrac{n}{i} ight floor)(leftlfloor dfrac{m}{i} ight floor)的右边界可能不同。所以,我们只要把这个分段再“切碎一点”就好了。

    直接参考代码来理解吧:

    for (int l = 1, r; l <= k; l = r + 1) {
        r = min(n / (n / l), m / (m / l));	// “切碎一点”
        r = min(r, k);	// 防止越界
        ans += (r - l + 1) * (n / l) * (m / l);
    }
    

    证明

    摘自:OI-Wiki

    PS:稍微吐槽一下OI-Wiki,OI-Wiki写的内容是很完备而且严谨的,所以对于初学来说反而有点痛苦。。。

    PSS:建议做一做OI-Wiki推荐的习题试试: 「luogu P2261」CQOI2007 余数求和

    对于任意给定的(i),我们要找一个最大的(j),满足(leftlfloor dfrac{n}{i} ight floor = leftlfloor dfrac{n}{j} ight floor)

    首先,我们证明(leftlfloor dfrac{n}{leftlfloor frac{n}{i} ight floor} ight floor geqslant i)

    [egin{align} & leftlfloor dfrac{n}{i} ight floor leqslant dfrac{n}{i} \ Longrightarrow & leftlfloor dfrac{n}{lfloor dfrac{n}{i} floor} ight floor geqslant leftlfloor dfrac{n}{dfrac{n}{i}} ight floor = lfloor i floor = i \ Longrightarrow & i leqslant leftlfloor dfrac{n}{lfloor dfrac{n}{i} floor} ight floor = j end{align} ]

    下证明:(leftlfloor dfrac{n}{leftlfloor frac{n}{i} ight floor} ight floor)是满足条件的最大的(j)

    (k = leftlfloor dfrac{n}{i} ight floor),那么,必然有(leftlfloor dfrac{n}{j} ight floor = k)显然,(j)的最大值是(leftlfloor dfrac{n}{k} ight floor)

    (有一说一,我确实觉得挺显然的)

    (leftlfloor dfrac{n}{j} ight floor = k Longleftrightarrow k leqslant dfrac{n}{j} < k + 1 Longleftrightarrow dfrac{1}{k + 1} < dfrac{j}{n} leqslant dfrac{1}{k} Longleftrightarrow dfrac{n}{k + 1} < j leqslant dfrac{n}{k})

    又因为(j)是整数,所以(j_{max} = leftlfloor dfrac{n}{k} ight floor)

  • 相关阅读:
    关于自带的sql developer修改java.exe版本的解决办法
    过滤器-用动态代理解决全站乱码
    myeclipse 文件注释部分乱码问题
    xml&dom_sax&dom4j的常见操作
    JSTL报错Unable to read TLD "META-INF/c.tld" from JAR file "file.............................
    机器学习--模型分类--贝叶斯
    机器学习中---分类模型--决策树模型
    分类模型的评估
    导数
    贝叶斯--- 高斯贝叶斯//多项式贝叶斯//伯努利贝叶斯
  • 原文地址:https://www.cnblogs.com/icysky/p/13726911.html
Copyright © 2020-2023  润新知