zoukankan      html  css  js  c++  java
  • 学习笔记 启发式合并

    启发式合并

    前言

    启发式合并十分得神奇,如果不刻意去想可能几乎想不到这种优化方法,但是在某些时刻看似是暴力的代码套上这几个字再加上证明复杂度,就能缩一圈,但没有模板,代码因题而异,十分灵活。

    概念简述

    • 对于 (n) 个初始大小为1的可重集,每次选择(被动)两个集合合并时,每次将 (S_1)(S_2) 合并的代价是其中一个集合的大小,而目的时合并成 (1) 个可重集的最小代价。

      每次合并,很显然的一种贪心方法是将较小的集合合并到较大的集合,复杂度为 (O(min(S_1,S_2))) ,而最后的时间复杂度的阶也很神奇,是 (O(nlog_2n))

    证明

    观察每次合并操作将较小的集合合并到较大的集合,而每个元素只有在较小的集合才会产生贡献,但每次合并操作对于较小的集合都会扩大一倍,而对于刚开始的大小为 (1) 的集合,最多会带此元素作为较小的集合扩大 (lfloorlog_2n floor) 次,而每个元素扩大 (lfloorlog_2n floor) 次后复杂度为 (O(nlog_2n)) ,对于随机数据完全达不到这个上限,我们还是保守的将其估计为此。

    例题

    (持续更新ing)

    • (large exttt{LG U41492})

      树上启发式合并模板题。

      将问题转换到了树上,其实就是规定了每次操作合并的两个可重集。

      在 DFS 遍历到某个节点的时候保留一颗最大的子树的答案,再将其它兄弟子树所有节点后合并到那颗最大的子树的答案中,得到父亲节点的答案。

      在一个节点中,每次对于要合并的子树大小最少扩大一倍,而对于某个节点,它在较小的子树中合并产生贡献为包括它的所有子树的合并次数,而这个合并次数不超过 (log_2n) ,因此合并次数也是不超过 (O(nlog_2n)) (对于随机数据十分得松)。

  • 相关阅读:
    HDU 2089 不要62 数位dp入门
    The Chosen One
    linux100讲——12 创建和删除目录
    linux100讲——80 系统函数库介绍
    linux100讲——03 什么是linux
    linux100讲——71 if-else判断的使用
    查看僵尸进程
    虚拟机出问题 Oh no,something has gone wrong! 解决方法
    禅道开源手册
    多线程启动selenium,报NameError: name '__file__' is not defined
  • 原文地址:https://www.cnblogs.com/RedreamMer/p/14518380.html
Copyright © 2011-2022 走看看