当前位置: 首页 > news >正文

分块

分块不仅算是一种数据结构,也算是一种思想,一般用均值不等式求出最优值,一般带根号

\(\log\) 下面即根号,想不出别的数据结构维护方法,就想根号!

数论分块

\(\sum_{i=1}^{n} \lfloor \frac{n}{i} \rfloor\),这玩意数量级为 \(O(n\log n)\)

\(1\sim n\) 分成若干个块,对于 \(i\),块的右端点为 \(\lfloor \frac{n}{\lfloor \frac{n}{i}\rfloor}\rfloor\)

for(int l=1,r;l<=n;l=r+1) {r=n/(n/l);ans+=(r-l+1)*(n/l);
}

区间数(不同值种类)为 \(O(\sqrt n)\)

数论上的分块思想总伴随的倍数,值域极大

AT_arc068_c [ARC068E] Snuke Line

考虑对于一个区间 \([l_i,r_i]\),如果存在 \(x\) 满足 \(l_i\le d\times x\le r_i\),那么这个区间对 \(d\) 有贡献,即如果存在 \(\lfloor \frac{l_i-1}{d} \rfloor<x\le \lfloor\frac{r_i}{d}\rfloor\),也就是如果 \(\lfloor \frac{l_i-1}{d} \rfloor < \lfloor\frac{r_i}{d}\rfloor\),那么这个区间对 \(d\)

上面是一维数论分块,扩展到二维分块,即对于 \(n_1,n_2\),将 pair\((\lfloor\frac{n_1}{i}\rfloor,\lfloor\frac{n_2}{i}\rfloor)\) 相同的 \(i\) 分在一块,容易知道块的数量为 \(O(\sqrt n)\)

对于每一块,如果满足上述条件,那么此区间就对这一块的 \(d\) 有贡献,这个贡献可以通过差分统计

for(int l=1,r1,r2,r;l<=x;l=r+1) {r1=x/(x/l);r2=y/(y/l);r=min(r1,r2);if(x/l<y/l) ++d[l],--d[r+1];
}

根号分治

根号分治和数据结构中的分块并不能混为一谈,根号分治更是一种思想,将不同的暴力(\(O(B),O(\frac{n}{B})\) )的优势拼在一起,从而达到一个平衡下复杂度不错的东西。

洛谷P8250 交友问题

先想一想暴力:

  1. 直接枚举 \(u\) 的所有出边,并判断这些出边和 \(v\) 的出边有多少重复的

    直觉上如果 \(u\) 的出边比较少,再用一个 \(\log\) 就可以判断了

  2. 如果 \(u\) 的出边很多,枚举就会达到 \(O(nq)\),我们需要快速判断有多少人既是 \(u\) 的朋友也是 \(v\) 的朋友。用 b[u]&b[v] 来表示就可以了,用 bitset 可以做到时空都是 \(O(\frac{n}{w})\)

时间是 1.2e9 空间 1e8

假设以 \(B\) 为分界,方法一的时间 \(O(n B\log n)\),方法二时间\(O(\frac{n}{w})\),空间为 \(O(\frac{n^2}{B})\),让 \(B=\sqrt{\frac{n}{\log n}}\),理论上要让 B 稍微大一点

ARC052D 9

\(10^{10}\) ,第一眼应该是数位 dp,比如设 \(f_{i,j,k,0/1}\),当前考虑到第 \(i\) 数位,余数为 \(j\),数位和为 \(k\),是否顶到了最大的 \(M\)

注意到数位和最大为 90,但是 \(j\) 也就是 \(K\) 可以很大。但是当 \(K\) 很大的,对于一个固定的数位和 \(i\),只有 \(\frac{M}{k}\) 种,这个可能很小。

那么对 \(K\) 设定一个阈值,平衡后就可以做到根号了。

CF1039D You Are Given a Tree

首先对于一个固定的 \(k\) 暴力怎么求出答案,从子树开始遍历,只要能拼成 \(k\) 路径那么就拼,这样一定是最优的。那么就可以通过 \(O(n)\) 的 DP 来解决一个 \(k\)

注意 \(k\) 的答案单调不减,那么可以考虑二分。

继续观察,\(k\) 越大,答案越密集,注意到当 \(k\ge \sqrt n\) 时,\(ans\le \sqrt n\) ,如果枚举的是答案,然后二分出答案区间即可。

复杂度可以做到 \(O(n\sqrt{n\log n})\)

块状数组

更偏向于一种数据结构。将一个数组分为几个块,块内信息整体维护,查询时的散点暴力查询。

P2801 教主的魔法

开一个新的数组 \(t\),维护每一个块顺序,这样查找的时候每一个块一个 \(\log\) ,总复杂度为 \(O(q\log n\sqrt n)\)

P5356 [Ynoi Easy Round 2017] 由乃打扑克

动态区间第 \(k\) 小,事实上区间第 \(k\) 大的数可以通过二分一个数,再判断这个数的排位,不断二分得到答案

对于此题也可以每个块维护有序,每次查询就二分一个数,然后每个块判断,复杂度 \(O(q\log V\log n \sqrt n)\)

块状链表

链表插入为 \(O(1)\),但是查询为 \(O(n)\),而数组相反,那么两者结合一下,维护若干个块,每个块是一个链表,当链表数量超过 \(2B\) 的时候就重构。

树分块

考虑能将树上任意路径都分成 \(\sqrt n\) 的方法,在树上撒 \(\sqrt n\) 的点,并保证这些点任意两个点的距离 \(\ge \sqrt n\),具体操作如下:

void dfs1(int u,int f) {mxd[u]=dep[u]=dep[f]+1;for(int v : g[u]) {if(v==f) continue;dfs1(v,u);}if(mxd[u]-dep[u]>B) {mxd[u]=dep[u];id[u]=++tot;}
}

这样任意路径分为 \(\sqrt n\),每一块我们都预处理,将路径看成序列来做就行了。

P6177 Count on a tree II/【模板】树分块

http://www.wuyegushi.com/news/451.html

相关文章:

  • 并查集
  • 7-27
  • CVE-2021-21311 服务器端请求伪造(SSRF)漏洞 (复现)
  • 【Rag实用分享】小白也能看懂的文档解析和分割教程
  • 【纯干货】三张图深入分析京东开源Genie的8大亮点
  • JoyAgent综合测评报告
  • 【EF Core】为 DatabaseFacade 扩展“创建”与“删除”数据表功能
  • 亚马逊机器学习大学推出负责任AI课程 - 聚焦AI偏见缓解与公平性实践
  • FFmpeg开发笔记(七十八)采用Kotlin+Compose的NextPlayer播放器
  • 4.5.4 预测下一个PC
  • 第十六日
  • 2025“钉耙编程”中国大学生算法设计暑期联赛(3)
  • VMware Windows Linux Macos网盘下载
  • ZBrush 2025 中文版免费下载,附图文安装指南,小白也能快速上手!
  • k8s network
  • hyprland初尝试
  • 正则表达式 更新常用则表达式-----loading
  • 幼儿园小班线段树
  • 树02
  • 深入ADC采样
  • 学习笔记:MySQL :eq_range_index_dive_limit参数
  • Python字符串知识点总结
  • SQL Server 2025年7月更新 - 修复 CVE-2025-49718 Microsoft SQL Server 信息泄露漏洞
  • 读书笔记:Oracle数据库内存结构:系统全局区(SGA)详解
  • 小飞标签
  • 服务器配置的精细化控制(3960)
  • TCP连接优化的实战经验(7340)
  • 家庭主妇人到中年的生活困境很难突破防
  • 中间件架构的优雅实现(0454)
  • 梦醒时分