数学--数论--整除分块(巨TM详细,学不会,你来打我)
1.概念
从一道例题说起
在介绍整除分块之前,我们先来看一道算数题:已知正整数n,求∑i=1n⌊ni⌋已知正整数n,求∑i=1n⌊ni⌋在介绍整除分块之前,我们先来看一道算数题:
已知正整数n,求∑i=1n⌊ni⌋\begin{aligned}已知正整数n,求\sum_{i=1}^n \left⌊\dfrac{n}{i}\right⌋\end{aligned}在介绍整除分块之前,我们先来看一道算数题:已知正整数n,求∑i=1n⌊ni⌋已知正整数n,求i=1∑n⌊in⌋
我们写一个表格看一看1-20的整除是什么样子的
| i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ⌊20i⌋\left⌊\dfrac{20}{i} \right⌋⌊i20⌋ | 20 | 10 | 6 | 5 | 4 | 3 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
表中同样的值会连续出现,而相同的值所划分的区间积是整出分块。整除的性质使得从1到n的数组表可根据数值划分为不同的分块,且分块数远远小于n。利用这种性质,我们如果能推导出每个分块具体的左右端点位置在哪,这个问题就可以快速求解出来了。
2.整除分块公式推导
向下取整的情形
还是说我们的例题
已知正整数n,求∑i=1n⌊ni⌋已知正整数n,求\sum_{i=1}^n \left⌊\dfrac{n}{i}\right⌋已知正整数n,求∑i=1n⌊in⌋
假设我们已知某一个分块的左端点lll,要求解出该分块的右端点rrr。设该分块的数值为kkk,对于该分块中的每个数iii,有k=⌊ni⌋=⌊nl⌋k=\left⌊\dfrac{n}{i}\right⌋=\left⌊\dfrac{n}{l}\right⌋k=⌊in⌋=⌊ln⌋,即ik≤nik\le nik≤n,也就是说我们找到可得使ik≤nik\le nik≤n成立的最大的i的值即是我们所求的右端点r,因此我们可以得到下列式子:
{k=⌊nl⌋ r=max(i),ik≤n\begin{cases}k = \left⌊\dfrac{n}{l}\right⌋ \\\space \\r = \max (i), ik \le n\end{cases}⎩⎪⎪⎨⎪⎪⎧k=⌊ln⌋ r=max(i),ik≤n
推导可得:
r=⌊nk⌋=⌊n⌊nl⌋⌋r= \left⌊\dfrac{n}{k}\right⌋=\left⌊\dfrac{n}{\left⌊\dfrac{n}{l}\right⌋ }\right⌋r=⌊kn⌋=⎣⎢⎢⎢⌊ln⌋n⎦⎥⎥⎥
容易得到代码:
ans = 0;
for(int l = 1, r; l <= n; l = r + 1)
{
r = n / (n / l);
ans += n / l * (r - l + 1);
}
But 还没有结束
我们再看这一道题:
已知正整数n,a,b,求∑i=1n⌊nai+b⌋\begin{aligned}已知正整数n, a, b, 求\sum_{i=1}^n \left⌊\dfrac{n}{ai + b} \right⌋\end{aligned}已知正整数n,a,b,求i=1∑n⌊ai+bn⌋
抓瞎了,但是变变形应该可以做。
我们记得
{k=⌊nl⌋ r=max(i),ik≤n\begin{cases}k = \left⌊\dfrac{n}{l}\right⌋ \\\space \\r = \max (i), ik \le n\end{cases}⎩⎪⎪⎨⎪⎪⎧k=⌊ln⌋ r=max(i),ik≤n
r=⌊nk⌋=⌊n⌊nl⌋⌋r= \left⌊\dfrac{n}{k}\right⌋=\left⌊\dfrac{n}{\left⌊\dfrac{n}{l}\right⌋ }\right⌋r=⌊kn⌋=⎣⎢⎢⎢⌊ln⌋n⎦⎥⎥⎥
以上两个公式,我们有如下
{k=⌊nal+b⌋ r=max(i),(ai+b)k≤n\begin{cases}k = \left⌊\dfrac{n}{al+b}\right⌋ \\\space \\r = \max (i), (ai+b)k \le n\end{cases}⎩⎪⎪⎨⎪⎪⎧k=⌊al+bn⌋ r=max(i),(ai+b)k≤n
上式子可推导为

但是对于这个题目,我们给出第二种推导方式,使得一种推导方式解决多种题目。

这我们再做
已知正整数n,求∑i=1n⌊ni2⌋\begin{aligned}已知正整数n, 求\sum_{i=1}^n \left⌊\dfrac{n}{i^2} \right⌋\end{aligned}已知正整数n,求i=1∑n⌊i2n⌋
我们按照上面的方式推导

不知道这时候有多少人偷笑,说自己把整除分块学会了,曾经以为自己是个王者,结果他爸来。

这个题你懵了吗,对于一对 L和R,中间的值是等差数列,相差1,归根结底还是整除分块,还是找到l和r,通过等差数列计算即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n, k, ans = 0;
long long left = 1, right, rest;
scanf("%lld%lld", &n, &k);
while (left <= n && left <= k) //求从1到min(n, k)内的总和
{
right = min(k / (k / left), n);
rest = k % left;
ans += (rest + rest - (right - left) * (k / left)) * (right - left + 1) / 2;
left = right + 1;
}
if (n > k)
{
ans += k * (n - k);
}
cout << ans;
}

王者你会了吗?
王者自信满满的说自己会了!
王者再看看这个题
已知正整数n,求∑i=1n⌈ni⌉已知正整数n,求\sum_{i=1}^n \left⌈\dfrac{n}{i}\right⌉已知正整数n,求∑i=1n⌈in⌉
没4没4,我们就不推导向上取整了,这里只需要一个小转化,将向上取整转化为向下取整。
我们考虑没有整除的时候是不是就有
⌈ni⌉=⌊ni⌋+1\left⌈\dfrac{n}{i}\right⌉ =\left⌊\dfrac{n}{i}\right⌋+1⌈in⌉=⌊in⌋+1 如果整除的时候就相等了,那么我们只要不加1,我们加上i−1i\dfrac{i-1}{i}ii−1就可以避免这种情况,那么就可以转化为

通过上面向下取整的推到即可得到

到这里王者就可以独当一面了。
数学--数论--整除分块(巨TM详细,学不会,你来打我)的更多相关文章
- CodeForces 1202F(数论,整除分块)
题目 CodeForces 1213G 做法 假设有\(P\)个完整的循环块,假设此时答案为\(K\)(实际答案可能有多种),即每块完整块长度为\(K\),则\(P=\left \lfloor \fr ...
- [POI2007]ZAP-Queries (莫比乌斯反演+整除分块)
[POI2007]ZAP-Queries \(solution:\) 唉,数论实在有点烂了,昨天还会的,今天就不会了,周末刚证明的,今天全忘了,还不如早点写好题解. 这题首先我们可以列出来答案就是: ...
- [笔记] 整除分块 & 异或性质
整除分块 参考资料:整除分块_peng-ym OI生涯中的各种数论算法的证明 公式 求:\(\sum_{i=1}^{n}\lfloor\frac{n}{i}\rfloor\) 对于每个\(\lfloo ...
- P2261 [CQOI2007]余数求和[整除分块]
题目大意 给出正整数 n 和 k 计算 \(G(n, k)=k\ \bmod\ 1 + k\ \bmod\ 2 + k\ \bmod\ 3 + \cdots + k\ \bmod\ n\) 的值 其中 ...
- luogu2261余数求和题解--整除分块
题目链接 https://www.luogu.org/problemnew/show/P2261 分析 显然\(k\) \(mod\) \(i=k-\lfloor {k/i}\rfloor\) \(\ ...
- 51Nod 1225 余数之和 [整除分块]
1225 余数之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 F(n) = (n % 1) + (n % 2) + (n % 3) + ... ...
- [Bzoj 2956] 模积和 (整除分块)
整除分块 一般形式:\(\sum_{i = 1}^n \lfloor \frac{n}{i} \rfloor * f(i)\). 需要一种高效求得函数 \(f(i)\) 的前缀和的方法,比如等差等比数 ...
- P2568 莫比乌斯反演+整除分块
#include<bits/stdc++.h> #define LL long long using namespace std; ; bool vis[maxn]; int prime[ ...
- LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)
题面 LOJ #2802. 「CCC 2018」平衡树 题面有点难看...请认真阅读理解题意. 转化后就是,给你一个数 \(N\) ,每次选择一个 \(k \in [2, N]\) 将 \(N\) 变 ...
随机推荐
- 家庭版记账本app开发进度相关界面的规划
总的app界面包括四个页面,页面可以来回滑动.设计的时候就和微信的四个页面类似. 由于没有找到合适的图标进行替换,在此仍应用微信对应的四个图标. 总的四个页面是: 1.增加收入或者支出的小账单.当点击 ...
- go中的面向对象总结
我们总结一下前面看到的:Go 没有类,而是松耦合的类型.方法对接口的实现. OO 语言最重要的三个方面分别是:封装,继承和多态,在 Go 中它们是怎样表现的呢? 封装(数据隐藏):和别的 OO 语言有 ...
- python学习 0 python简介
一.Python简介 python是一门简单易学又功能强大的编程语言.它具有高效的高级数据结构和简单而有效的面向对象编程的特性.python优雅的语法和动态类型.以及其解释性的性质,使它在许多领域和大 ...
- jvm入门及理解(四)——运行时数据区(堆+方法区)
一.堆 定义: Heap,通过new关键字创建的对象,都存放在堆内存中. 特点 线程共享,堆中的对象都存在线程安全的问题 垃圾回收,垃圾回收机制重点区域. jvm内存的划分: JVM内存划分为堆内存和 ...
- networkx学习与攻击转移图可视化
接到一个任务,将攻击转移矩阵进行可视化,生成攻击转移概率图,便尝试用python实现一下. 查阅资料,看大家都在用networkx和matplotlib进行可视化,便边学边做,记录一下学习笔记. 任务 ...
- 一个不错的java学习博客
http://iteye.blog.163.com/blog/static/18630809620131484835129/
- string 从下标0 一直截到倒数第三位
StringUtils.substring(String.valueOf(maxSequence), 0, -3)如上,关键就是那个-3,表示倒数第三位.
- OS X10.10.3正式版和Xcode 6.3正式版下载
4.09日,OS X10.10.3 正式版 IOS8.3 正式版和 Xcode 6.3 正式版在今天发布,这是 2015 年里面,IOS 系统和 Mac OS 系统,以及 IOS 和 Mac OS 专 ...
- C#多线程(6):线程通知
目录 AutoRestEvent 类 常用方法 一个简单的示例 解释一下 复杂一点的示例 解释 回顾一下,前面 lock.Monitor 部分我们学习了线程锁,Mutex 部分学习了进程同步,Sema ...
- Python数据可视化---pygal模块
目录 pygal模块 安装pygal模块 pygal模块介绍 柱状图 单列柱状图 堆叠柱状图 横向柱状图 折线图 简单折线图 纵向折线图 堆叠折线图 饼状图 简单饼状图 多级饼状图 圆环图 半圆图 雷 ...