数论分块之整除分块

前言

最近在学莫比乌斯反演,然而只看懂了莫比乌斯函数,然后反演看着一脸懵逼,最后只看懂了数论分块里面的一个分支内容(也是莫比乌斯反演的前置姿势),整除分块
于是写一篇博文记录一下整除分块

整除分块

整除分块是用于快速处理形似
\[
\sum_{i=1}^{n}{\lfloor \frac{n}{i} \rfloor}
\]
的式子的方法
很显然,这个可以\(O(n)\)得到答案。但是,在某些题目中,毒瘤出题人将数据加强到了\(10^{10}\)以上,这个时候我们就无法通过\(O(n)\)的解法来得到答案了。我们需要一个\(O(\sqrt{n})\)的更为优秀的解法
首先观察这个式子,找几个特殊值代入
n=5时,sum=5+2+1+1+1
可以发现的是:(这里给的例子并不明显,其实应该找一个大的n来代入才直观,读者可以自行尝试)
对于单一的\(\lfloor \frac{n}{i} \rfloor\),某些地方的值是相同的,并且呈块状分布
通过进一步的探求规律与推理以及打表与瞎猜,我们可以惊喜的发现一个规律,这些块状分布的值是有规律的
对于一个块,假设它的起始位置的下标为l,那么可以得到的是,它的结束位置的下标为\(\lfloor \frac{n}{\lfloor \frac{n}{l}\rfloor} \rfloor\)
如果实在看的有点懵逼,可以继续采用代入特殊值的方法,验证一下上方的规律,用程序表现出来即为

//l为块的左端点,r为块的右端点
r=n/(n/l)

在实际应用中,需要注意的就是除法除0的问题(一般都需要特判一下n/l)
程序实现也十分简单

int ans = 0;
for(int l = 1, r = 0; l <= n; l++) {
    r = n / (n / l);
    // do something
}

实际应用

例题:BZOJ1257: [CQOI2007]余数之和

这题其实就是求
\[
\sum_{i=1}^{n}{k\space mod\space i}
\]
这题和整除分块又有什么关系呢?
mod没有什么特殊的性质,所以我们将它展开来,就变成了
\[
\sum_{i=1}^{n}{k\space-\lfloor \frac{k}{i} \rfloor*i}
\]
于是我们就看到了一个熟悉的形式,也就是整除分块的一般形式

再次改一下这个式子
\[
n*k-\sum_{i=1}^{n}{\lfloor \frac{k}{i}\rfloor*i}
\]
那么\(\sum_{i=1}^{n}{\lfloor \frac{k}{i}\rfloor*i}\)和普通的整除分块有什么差别呢?

其实就是多了一个i

确实,就是多了一个i而已,只需要简单的化简一下,这个i就对我们的处理没有什么影响了

因为我们知道,对于一个整除分块\(\sum_{i=l}^{r}{\lfloor\frac{k}{i}\rfloor}\),其中的每个值都是相同的,于是我们可以设\(T=\lfloor\frac{k}{i}\rfloor\)

式子就化为了
\[
\sum_{i=l}^{r}T*i \=T*\sum_{i=l}^{r}i
\]
也就是说,其实这个式子前半段是一个整除分块,后半段是一个首项为l,公差为1的等差数列

至此,我们就圆满的解决了这个问题,可以在\(O(\sqrt{n})\)的时间内解决本题

这是整除分块中最基础的应用,就是单纯的利用整除分块来加速递推的实现,而实际上,整除分块更多的与其他函数结合在一起来使用,优化问题的求解

整除分块与积性函数

说到积性函数,就不得不讲到两个广为人知的函数\(\phi,\mu\),这是我们最熟悉的积性函数(其实我也只知道这两个)
积性函数有一个很好用的性质(设\(f(i)\)为一个积性函数):
\[
f(i*j)=f(i)*f(j)
\]
这里的\(f(i)\)其实是一个完全积性函数。(\(\phi\)就不是一个完全积性函数:\(\phi(i*j)=\phi(i)*\phi(j)\)当且仅当i,j互质才成立)
好了,讲完积性函数的这个性质后我们步入正题,整除分块与积性函数的联系
很多时候,我们推出来整除分块的式子不是很裸的,常与其他函数结合(通常是积性函数,通常为\(\mu\)或\(\phi\))
这个时候如何统计答案呢?
比如:
\[
\sum_{i=1}^{n}{\mu(i)*\lfloor \frac{n}{i}\rfloor}
\]
积性函数的性质!
因为积性函数这个很好用的性质,所以我们可以直接对前半段的莫比乌斯函数维护一个前缀和,再利用整除分块处理式子的后半段,处理答案的时候,把两段相乘即可
当然,整除分块能结合的函数肯定不止这么几个(但是由于博主太菜所以并不知道其他的函数与整除分块结合的方法)

\(To\ Be\ Continue...\)

原文地址:https://www.cnblogs.com/henry-1202/p/10121854.html

时间: 2024-11-06 07:17:56

数论分块之整除分块的相关文章

CodeForces 1202F(数论,整除分块)

题目 CodeForces 1213G 做法 假设有\(P\)个完整的循环块,假设此时答案为\(K\)(实际答案可能有多种),即每块完整块长度为\(K\),则\(P=\left \lfloor \frac{N}{K} \right \rfloor\) 假设循环快中有\(p_a,p_b\)个\(A\)和\(B\),则 \(p_a\cdot P\le a\Longrightarrow p_a\le \left \lfloor \frac{a}{P} \right \rfloor\) \(p_a\cd

luogu2261余数求和题解--整除分块

题目链接 https://www.luogu.org/problemnew/show/P2261 分析 显然\(k\) \(mod\) \(i=k-\lfloor {k/i}\rfloor\) \(\times\) \(i\),于是我们只需要求\(N * k-\sum_{i=1}^N {\lfloor {k/i}\rfloor\times i}\) 这里就需要数论分块,也称作整除分块的知识 结论: \(\forall{i} \in [x,\lfloor {k/{\lfloor {k/x}\rfl

[CQOI2007]余数求和-整除分块

题目 题目 题目大意: 给出正整数\(n,k\),求\(\Sigma_{i=1}^{n}{k \bmod i}\) 代码 乍一看只能暴力,其实稍微修改下就变成了数论分块. \(\Sigma_{i=1}^{n}{k \bmod i}=\Sigma_{i=1}^{n}{\lfloor{\frac{k}{i}}\rfloor} \times i\) 然后就比一般的整除分块只是多了一个i,套板子就行了. #include <iostream> using namespace std; typedef

LightOJ 1098(均值不等式,整除分块玄学优化)

We all know that any integer number n is divisible by 1 and n. That is why these two numbers are not the actual divisors of any numbers. The function SOD(n) (sum of divisors) is defined as the summation of all the actual divisors of an integer number

[Bzoj 2956] 模积和 (整除分块)

整除分块 一般形式:\(\sum_{i = 1}^n \lfloor \frac{n}{i} \rfloor * f(i)\). 需要一种高效求得函数 \(f(i)\) 的前缀和的方法,比如等差等比数列求和或对于积性函数的筛法等,然后就可以用整除分块的思想做. 题目解法 化公式变成比较方便的形式: \(\ \sum_{i = 1}^n \sum_{j = 1}^m (n \mod i)(m \mod j), i \ne j\) \(= \sum_{i = 1}^n \sum_{j = 1}^m

UVALive - 3521 Joseph&#39;s Problem (整除分块)

给定$n,k$$(1\leqslant n,k\leqslant 10^9)$,计算$\sum\limits _{i=1}^nk\: mod\:i$ 通过观察易发现$k\%i=k-\left \lfloor \frac{k}{i} \right \rfloor*i$,因此我们考虑把$\left \lfloor \frac{k}{i} \right \rfloor$的值相同的$i$分成一组直接求和,复杂度为$O(\sqrt{n})$. 整除分块原理(选自某dalao博客) 1 #include<b

整除分块模板

这里大概讲解一下整除分块的原理和效果. 比如我们要求某个i的区间中,n/i的和是多少,但是其实你会发现,在一些连续的区间中,n/i是相等的,而整除分块的目的,便是按照n进行分块 使得可以跳过这些n/i是相等的这些区间,使得复杂度将到根号n for (int l=1,r;l<=n;l=r+1){ r=n/(n/l); // printf("%d ",r); } 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/10600035.html

【纪中集训2019.3.29】整除分块

题目 描述 ? 本题的背景是整除分块: ? 定义一个数列$a_{n,i} ? = ?\lfloor \frac{n}{i} \rfloor $ ; ? 求$\sum_{i=l}^{r} mex(a_n) $ ; ? 其中\(mex\)表示序列中最小的没有出现过的自然数: ? 答案对\(998244353\)取模 : 范围 ? \(1 \le T \le 65536 \ , \ 1 \le l ,r \le 10^{36}\) : ? 评测系统支持使用 $ _ _ int218 $ ,但是不能直接

C. Everyone is a Winner!(整除分块)

传送门 题意: 输入一个数n,求出n/i(i取任意)向下取整有几种数,并输出 思路: 整除分块裸题 for(int l=1,r;l<=n;l=r+1) { r=n/(n/l); a[++cnt]=n/l; }   cnt代表分块的块的个数,每个块里的值为a[i]=n/l,l为块的左端点,r为块的右端点r=n/(n/l) 代码: #include <iostream> #include <stdio.h> #include <algorithm> #include