本文转自http://fanhq666.blog.163.com/blog/static/81943426201172472943638/

求树重心的方法:(NlogN)

http://www.cnblogs.com/qlky/p/5780933.html

还记得曾经提到过的树的“重心”吗?重心的定义是:以这个点为根,那么所有的子树(不算整个树自身)的大小都不超过整个树大小的一半。
 

树的重心的一个的性质:

树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么他们的距离和一样。
这也是“道路修建”带来的启发。(证明:调整法)
 
树的重心的另一个性质:
把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上。
这个让“重心”名副其实了。。。(证明:。。。自己好好思考一下吧。。。)
 
还有一个性质:
把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
(证明:提示:张放想都没想说,要不然那两个不等式就矛盾了)
 
嗯,不错,有这么多性质,可以出不少恶心题了。。。
 
不过,我还是更关心一个事情:重心的动态维护。
如何动态呢?
情景1:添加一片叶子
根据已有性质,添加一片叶子之后新的重心要么不动要么向那片叶子的方向移动一下。这样,可以用一个link-cut tree来维护。
我们以重心为根建立这个动态树。每个节点维护它所在的子树的大小。添加叶子等于向一条路径上的维护值增加1,这个可以通过打标记实现。发现不得不移动的时候进行一次换根的操作。因为只可能移动1,所以换根的操作是可以完成的。
我们甚至还可以维护所有点到重心的距离和!这个只需给每个点加一个维护值:这个点为根的子树中所有点到这个点的距离和,通过稍微有点复杂的标记系统还是可以维护的。
 
情景2:删除一片叶子
只有删除操作?那么离线改成添加吧。。。
不允许离线?那么我们要换一个思路:
定义稍微广义的树的重心:每个点有一个非负权,每个边有个正的长度,到所有点的权乘以距离的和最小的点定义为重心。
注意:树的重心的位置和边的长度没有关系!。
在只有权值修改的情况下,我们可以利用树分治配合基本数据结构来维护树的重心:
注意到,我们可以维护一个子树内的点的权值和(利用dfs序)。这样给定一条边,我们就能够知道树的重心在这条边的哪边(看看哪边权值和大就行了)。
这样,我们可以先找一个比较靠近中心的边,问问应该向哪边走,再分治下去,就像树分治那样(类似二分查找?)。
当然,要想一下其他的技巧来对付”星型数据“,这个应该不难(通过拆点、拆边的技巧)。
利用这个广义一点的重心,我们发现,删除操作其实就是把权修改成0而已,可以在log^2N的时间内动态维护了。
如何处理多重心的情况?”抖动“一下权值使得只有一个重心不就行了。。。那另一个重心在哪里?这个只是个细节问题。。。
能否维护距离和?能否在logN的时间内维护?欢迎讨论(将子树和查询与树分治结合起来?。。。)。
 
情景3:移动一片叶子
把一个叶子移动到另一个地方。
这个怎么维护呢?其实,我们发现,新的重心应该在原来的重心和叶子新的位置的连线上(证明?应该是对的吧),移动距离很小。于是,也就可以维护了。
 
情景4:移动一个子树(被移动的子树小于原树的一半,并且保持它的根不变)
这个可以维护吗?
新的重心在原来重心和新子树的接合点的连线上吗?(证出来的欢迎留言)
有一个可以和link-cut tree配合使用的工具,叫做Euler-tour tree,它维护树的欧拉回路,基本元素是边。利用它,可以方便的完成子树的移动,并且给定一条有向边,可以回答这条边指向的子树的大小(Eurler-tour tree中没有”根“以及”父亲“这个概念!)。如果上面的那个论断是对的,那么这个应该可以维护了(复杂度?log^2N吧。。。)
另一个思路是树块划分,把树划分成若干联通块,并且在查询的时候合并相邻的联通块使得每个联通块的大小都是sqrt(N)的级别。这个东西对维护是否有帮助?欢迎交流。。。
 
情景5:开始N个一个点的树,每次用一条边合并两个树,要求回答新的树的重心
离线?在线?logN?log^2N?sqrt(N)?
等待你去探索
 
情景6:未来的某一天,某省省选出了一个叫做”疯狂的重心“的数据结构题,时限1分钟,内存若干G,标程几十K,当场无人做。。。。。。

ACM-树重心的性质及动态维护的更多相关文章

  1. 树上的构造 树分治+树重心的性质 Codeforces Round #190 (Div. 2) E

    http://codeforces.com/contest/322/problem/E E. Ciel the Commander time limit per test 1 second memor ...

  2. BZOJ 3510 - 首都 「 $LCT$ 动态维护树的重心」

    这题 FlashHu 的优化思路值得借鉴 前置引理 树中所有点到某个点的距离和中,到重心的距离和是最小的. 把两棵树通过某一点相连得到一颗新的树,新的树的重心必然在连接原来两棵树重心的路径上. 一棵树 ...

  3. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  4. bzoj3991 [Sdoi2015]寻宝游戏 set动态维护虚树+树链求并

    题目大意:支持多次操作,增加或删除一个关键点 动态维护虚树边权和*2 分析:可以用树链求并的方法,最后减去虚树的根到1距离 注意到树链求并是所有点到根距离-所有dfn序相邻两点的LCA到根距离 找df ...

  5. BZOJ3159决战——树链剖分+非旋转treap(平衡树动态维护dfs序)

    题目描述 输入 第一行有三个整数N.M和R,分别表示树的节点数.指令和询问总数,以及X国的据点. 接下来N-1行,每行两个整数X和Y,表示Katharon国的一条道路. 接下来M行,每行描述一个指令或 ...

  6. 【bzoj4184】shallot 线段树+高斯消元动态维护线性基

    题目描述 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱从自己手中的小 ...

  7. 2019 ICPC上海网络赛 A 题 Lightning Routing I (动态维护树的直径)

    题目: 给定一棵树, 带边权. 现在有2种操作: 1.修改第i条边的权值. 2.询问u到其他一个任意点的最大距离是多少. 题解: 树的直径可以通过两次 dfs() 的方法求得.换句话说,到任意点最远的 ...

  8. Splay伸展树入门(单点操作,区间维护)附例题模板

    Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...

  9. 【BZOJ4025】二分图(LCT动态维护图连通性)

    点此看题面 大致题意: 给你一张图以及每条边的出现时间和消失时间,让你求每个时间段这张图是否是二分图. 二分图性质 二分图有一个比较简单的性质,即二分图中不存在奇环. 于是题目就变成了:让你求每个时间 ...

随机推荐

  1. completer自动完成

    由于项目需要,在输入框中要做一些输入限制的同时,更加要求用户体验,提供一些自动完成设置.所以有需求,总会有解决方式,下面说一下自动完成插件的原理: html的body部分: <span styl ...

  2. loj #2044. 「CQOI2016」手机号码

    #2044. 「CQOI2016」手机号码 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  3. SIGHUP信号

    SIGHUP会在以下3种情况下被发送给相应的进程:1.终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)2.session首进程退出时,该信号被 ...

  4. asp.net core 简化模型验证 modelState.IsValid不用每一个写

    第一种:直接在执行action之前验证模型 实现 IActionFilter public class ModelStateFilter : IActionFilter { public void O ...

  5. 禁止百度转码和百度快照缓存的META声明

    今天手机 site 中国博客联盟时,发现网被转码了,虽然这个网站没做移动站,但是我也不希望被百度转码,因为这相当于拦截了所有来自手机的流量.下面说一下禁止百度转码和禁止百度快照缓存的方法. 一.禁止百 ...

  6. eclipse项目中的java文件导入后变为空心J问题

    1,选择工程名字右键——>属性——>JavaBuild Path会看到右侧Source标签中为空白 2,点击Add Folder...选择如图所示的src包和相关的配置文件包,点击确定: ...

  7. visio 使用技巧汇总

    1.visio中图形旋转任意角度的方法 视图----任务窗格----大小与位置----角度 2.箭头形状 更多形状---流程图----箭头形状 3.汇制虚线框 从基本形状中拖出一个矩形,右击矩形,选择 ...

  8. BAPC 2014:Button Bashing(暴力+bfs)

    题意: 给出n,m,代表微波炉有n个按钮,要求达到总时间为m 然后给出n个数,代表n个按钮能增加的时间,问最少几步,能够使得按出的总时间大于等于要求的时间,并且相差最小 输出最小的步数与相差的最小值 ...

  9. java mybatis学习一

    1.引入maven包 和 导入 sqljdbc包 <dependency> <groupId>org.apache.ibatis</groupId> <art ...

  10. Device eth0 does not seem to be present, delaying initialization: Linux Networking

    copy centos 报错 Device eth0 does not seem to be present, delaying initialization: Linux Networking # ...