基本技巧——根号分治 学习笔记

这篇具有很好参考价值的文章主要介绍了基本技巧——根号分治 学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基本技巧——根号分治 学习笔记

根号分治与其说是一个算法,更不如说是一种思想(trick)。

定义

根号分治,是一种对数据进行点分治的分治方式,它的作用是优化暴力算法;类似于分块,但应用范围比分块更广。

具体来说,对于所进行的操作,按照某个点 \(B\) 划分,分为大于 \(B\) 及小于 \(B\) 两个部分,两部分使用不同的方式处理。(一般以根号为分界,即 \(B = \sqrt n\),因为这样复杂度最平衡)

简而言之,根号分治就是:对数据范围分块处理,将多个暴力算法“拼接在一起”,实现优化复杂度的作用。

算法思路

理论基础

具体思路如下:

  • 对于数据的种类少的部分,可以全部维护;
  • 对于另一部分,不方便维护的,可以暴力求解。

题目特征

  1. 能将原问题分为一个大问题(即前文说的 \(>\sqrt n\))和一个小问题(即前文说的 \(<\sqrt n\));
  2. 小问题的情况不多,可以维护所有可能的答案用离线算法求解;大问题可以用暴力求解;
  3. 题目中某个值的总数量一定:比如图论中所有点的度数之和为 \(m\),或字符串长度为 \(n\)
  4. 数据范围长得比较奇怪,比如 \(10^{10}\),既不像是筛法,又不像是什么数位 DP。

求解方法

因此,一般来说,根号分治的题目可以分为预处理阶段枚举阶段

  • 预处理阶段:通过不同的算法将分成的两块分别计算;
  • 枚举阶段:将两部分合并为一个结果,通常会用到数学知识。

具体步骤:

  1. 找到两种暴力算法,复杂度分别为 \(O(b)\)\(O(n / b)\)
  2. 根据 \(n\) 的大小选取算法,则复杂度为:\(O(\min\{b, n / b\})\)
  3. 根据基本不等式,\(\min\{b, n / b\} \le n\)
  4. 取分界点 \(B = \sqrt n\),对分界点左、有分别选择较优的算法,复杂度降为 \(O(\sqrt n)\)

应用

例题

题目:P3396 哈希冲突

题意:给定长为 \(n\) 的序列 \(\mathrm{value}\),和 \(m\) 个操作:

  • A x y:询问 \(\sum\mathrm{value}_i\space[i \bmod x = y]\)
  • C x y:修改 \(\mathrm{value}_x = y\)
点击查看题解

考虑两种暴力解法:

  1. 预处理 模 \(i\)\(j\) 的下标,其中的元素之和;时间复杂度:\(O(n^2) + O(m)\)
  2. 暴力求 每次询问都遍历 \(\mathrm ki + j \space (\mathrm k \in \mathbb Z^+)\);时间复杂度:\(O(mn)\)

考虑优化,即将两种算法合并:

  1. 模数 \(< \sqrt n\):使用方法 \((1)\),时间复杂度:\(O(n \sqrt n) + O(m)\)
  2. 模数 \(> \sqrt n\):使用方法 \((2)\),时间复杂度:\(O(m \sqrt n)\)

因此,优化后的总时间复杂度为 \(O((n + m) \sqrt n)\)。代码如下:

const int N = 1.5e5 + 10;
const int M = 390;

int arr[N];
int f[M][M];

signed main() {
    int n = ur, m = ur; int b = sqrt(n);
    for (int i = 1; i <= n; ++i) {
        arr[i] = ur;
        for (int j = 1; j < b; ++j) f[j][i % j] += arr[i];
    } while (m--) {
        char op[2]; scanf("%s", op);
        int x = ur, y = ur; if (op[0] == 'C') {
            for (int i = 1; i < b; ++i) f[i][x % i] += y - arr[x];
            arr[x] = y;
        } else if (x < b) {
            printf("%d\n", f[x][y]);
        } else {
            int sum = 0; for (int i = y; i <= n; i += x) {
                sum += arr[i];
            } printf("%d\n", sum);
        }
    }
    return 0;
}

练习题

见:https://www.luogu.com.cn/training/386103

Reference

[1] https://blog.csdn.net/qq_35684989/article/details/127190872
[2] https://www.cnblogs.com/weixin2024/p/17032201.html
[3] https://www.luogu.com.cn/blog/Amateur-threshold/pu-li-mei-xue-qian-tan-gen-hao-fen-zhi
[4] https://zhuanlan.zhihu.com/p/594018645
[5] https://www.luogu.com.cn/blog/340940/gen-hao-fen-zhi-xue-xi-bi-ji
[6] https://www.cnblogs.com/ray52033/p/15011464.html
[7] https://www.luogu.com.cn/blog/blue/solution-p3396文章来源地址https://www.toymoban.com/news/detail-710517.html

到了这里,关于基本技巧——根号分治 学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PS CS6视频剪辑基本技巧(二)视频剪接和添加图片

    系列讲座导读 PS CS6视频剪辑基本技巧(一)CS6可以实现的视频剪辑功能 PS CS6视频剪辑基本技巧(二)视频剪接和添加图片 PS CS6视频剪辑基本技巧(三)添加声音和字幕 PS CS6视频剪辑基本技巧(四)字幕居中和滚动字幕 PS CS6视频剪辑基本技巧(五)添加logo、动画和画中画

    2023年04月15日
    浏览(52)
  • 异或运算的基本介绍以及使用技巧,剖析常见的异或题目

    异或运算,符号为‘^’,直接对底层二进制串进行运算,比算术运算快得多,规则为:相同为0,不同为1。 假设N为任意实数 性质1:0 ^ N = N 性质2:N ^ N = 0 性质3:异或运算满足交换律与结合律 重点:我们可以将异或运算理解为二进制的无进位相加!也就是说,当两个数异或

    2024年02月08日
    浏览(34)
  • 根号分治(根号算法)

    是根号算法,然而不是分块; 是论文,然而不是莫队; 是暴力美学,然而不是暴力。 哈希冲突 R e m a i n d e r P r o b l e m Remainder Problem R e main d er P ro b l e m 这两题貌似没有区别 ,我们以 R e m a i n d e r P r o b l e m Remainder Problem R e main d er P ro b l e m 作为例子来介绍。 给你一个长

    2024年03月20日
    浏览(31)
  • 浅谈根号分治——暴力的美学

    根号分治是一种优化暴力算法。 我个人的理解就是这东西跟 分块 差不多。但应用面比分块更广。 其核心思想就是 n n n 个数组成的数列,把它分成大于 N sqrt N N ​ 和小于 N sqrt N N ​ 的部分处理。 如果我们能对数据范围进行分块处理,或者两个暴力分别算之后拼接在一起,

    2024年02月11日
    浏览(22)
  • 【Python beautifulsoup】详细介绍beautifulsoup库的使用方法,包括安装方式、基本用法、常用方法和技巧,以及结合lxml和parsel的具体使用场景和区别。

    Python beautifulsoup库是一个强大的Web抓取和解析库,它提供了丰富的功能和简单易用的API,可以帮助我们处理HTML和XML文档,从中提取数据,进行数据清洗和处理。beautifulsoup库基于Python标准库中的html.parser模块,同时还可以与第三方解析库lxml和parsel配合使用,提供更高效和灵活的

    2024年02月04日
    浏览(47)
  • 【002JavaScript 类继承】基本继承、调用父类方法和混入模式等方面的知识。掌握类继承的概念和技巧,提升代码的灵活性和可维护性。

    在 JavaScript 中,类继承是实现代码复用和扩展的重要概念。通过继承,我们可以基于现有类创建新类,并继承父类的属性和方法。本文将详细介绍 JavaScript 类继承的各个方面和技巧。 使用 extends 可以实现基本的类继承。 } class Dog extends Animal { bark() { console.log( ${this.nam

    2024年02月08日
    浏览(48)
  • Codeforces Round 920 (Div. 3) F题 根号分治,后缀和,后缀和的后缀和

    Problem - F - Codeforces  我看的这位UP的视频讲解 : Codeforces Round 920 (Div. 3) F题 根号分治 详解_哔哩哔哩_bilibili   目录 题意: 思路: 后缀和的后缀和: 后缀和的后缀和的中间段如何求: ———— 根号分治: 核心代码:   给你个数组,求这个和 s是起始下标,d是间隔gap,k代表第

    2024年01月16日
    浏览(32)
  • CDQ分治学习笔记

    @ 目录 CDQ分治学习笔记 前言 CDQ分治思想 例题 1、翻转对 分析 code P3810 三维偏序(陌上花开) 输入格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 提示 分析 code 寒假作业 之前在gdkoi讲解是有人用 (CDQ) 分治A了day1 T3。好像分治FFT要用到,而且其他人都学过了,所以蒟蒻再次恶

    2024年02月01日
    浏览(19)
  • 「学习笔记」略谈点分治

    点分治适合处理大规模的树上路径信息问题。 给定一棵 (n) 个点树和一个整数 (k) ,求树上两点间的距离小于等于 (k) 的点对有多少。 对于这个题,如果我们进行 (O_{n^3}) 搜索,那只要 (n) 一大,铁定超时。 所以,我们要用一个更优秀的解法,这就是我们的点分治。

    2024年02月06日
    浏览(20)
  • Unity学习笔记——ScrollView常用技巧

    在学习UI过程中反复接触ScrollView,遇到了很多使用问题,有许多技巧需要记录下来 如果不使用横向滑动,只需要将ScrollView中的Horizontal取消即可,虽然在Unity视图中还会存在,但运行游戏后就会消失;纵向滑动条同理 另外,如果你的Content的范围设置太小,也是不会显示滑动条

    2024年02月09日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包