【Codechef】B-Tree
2016-03-02 21:16
267 查看
题目描述
给出一棵nn个点的树,边权都为11,以及mm个询问,每一个询问形式如下:给出kk个点的集合S={a1,a2,⋯,ak}S=\{a_1, a_2, \cdots, a_k\},以及每一个点的控制范围rair_{a_i}。
一个点pp称为被控制的,当且仅当∃x∈S,dis(x,p)≤rx\exists x\in S, dis(x, p)\leq r_x
问有多少个点被控制。
n,Q≤5×104,∑k≤5×105n, Q\leq 5\times 10^4, \sum k \leq 5\times 10^5
分析
part 1 简化的问题
不妨先看当k=1k=1时,问题变成怎么样的了。给出一棵树,每次询问距离点xx的距离小于rr的点的个数。
考虑点剖,每一个重心上存点剖子树中所有点,按照离重心距离为关键字建桶。
那么只需要在点剖树上,从xx往上跳,沿路统计答案就可以了。
但是注意可能会有重复计算。但是考虑点剖树上某个点只有lognlog n个祖先,将它们记录下来,逐个减去重复计算的就可以了。
时间复杂度O(log2n)O(log^2 n)
但是假如我们加入无用白点,那么这里可以O(1)O(1)地解决重复问题(只考虑另外两个儿子就可以了)
时间复杂度O(logn)O(log n )
边剖也是类似的,不过相对来说更加好写一点。
part 2 原问题的分解
扩展到多点 虚树
当k>1k>1时,我们可以引入虚树和控制范围的概念,从而将原问题转化。虚树的构建可以利用欧拉序,首先先将每两个相邻的关键点之间最近公共祖先都加入进去。然后维护一个栈,每加入一个点,就不断退栈,直到栈顶是它的某个祖先,然后将栈顶与这个点连边,最后将这个新点压入栈。
首先先构建出这kk个点的虚树,那么虚树中的每个点xx,它的控制范围lx=max0≤y<nly−disx,yl_x=max_{0\leq y,每个点的归属belongxbelong_x自然就是任意一个取得最大lxl_x的yy。
为了统一,假如某个点不被控制,不妨将lxl_x赋为00,belongxbelong_x赋为nn。
用spfa可以快速地计算出每个点的控制范围。
然后问题的答案就等于虚树上的每条边的答案之和。
单条边的处理方式
一条边的答案正着算似乎不好处理,用所有的虚树上点的控制范围点数和,减去重复的部分,也可以得到原来的答案。性质一:设(x,y)(x, y)是虚树上的一条边,那么当且仅当belongx≠belongybelong_x\neq belong_y时,才会在这条边上出现重复。
证明:显然。
性质二:对于满足性质一的边,存在唯一的z∈path[x,y]z\in path[x, y],使得path[x,z]path[x, z]上的点都属xx管劾,path(z,y]path(z, y]上的点都属yy管劾。
证明:
不妨令depx<depydep_x,那么
lx−dis(x,z)≤ly−dis(z,y)l_x-dis(x, z)\leq l_y-dis( z, y )
lx−(depz−depx)≤ly−(depy−depz)l_x-( dep_z-dep_x )\leq l_y-( dep_y-dep_z )
depx+depy+lx−ly≤2depzdep_x+dep_y+l_x-l_y\leq 2dep_z
⌈depx+depy+lx−ly2⌉≤depz\lceil \frac{ dep_x+dep_y+l_x-l_y }{2} \rceil \leq dep_z
由上面这条式子,就可以知道zz唯一确定了一条边之间两个点的管劾范围。
part 3 更深入的分析
通过这样的划分以后,我们计算答案的思路就变成下面两步
假如某个点在新图中存在势力范围,那么统计它势力范围内的点数,将其求和。
对于每条两个端点的统治势力不同的点,计算它们重叠部分并减去之。
对于第一个问题,套用“简化的问题”的思路,就可以简单地解决了。
对于第二个问题,实际上就是要统计距离不在点zz子树内,离zz距离小于等于lzl_z的点数,以及在zz的子树中,离点zz的距离小于等于lu−dis(z,u)l_u-dis(z, u)的点数。
那么对于第二个问题比较好的解决思路就是dfs序,因为子树都是dfs序中连续的一段,而不在子树中必定是全段挖去中间的一小段。那么我们只需要按dfs序构建主席树,那么就可以快速进行统计了。
那么单次询问的时间复杂度就是的时间复杂度O(klogn)O(klogn)
于是最终总的时间复杂度是O(nlogn+Qklogn)O( nlogn + Qklogn )
相关文章推荐
- 技术揭秘12306改造(一):尖峰日PV值297亿下可每秒出票1032张
- spring之IOC详解二
- 深度学习(二十六)Network In Network学习笔记-ICLR 2014
- dell服务器poweredge T620装ubuntu很卡显卡驱动有问题(matrox g200er2显卡)
- Java线程的创建和运行
- android通过jdbc远程连接SQL Server 并实现增删改查源码 jtds 1.3.1
- 面向对向六大原则——单一职责原则
- SSH之实现支付功能
- 从Oracle数据库中查询前几个月数据时需要注意的一些问题
- swift语言基础
- hdu2567 水题
- IIS调用COM组件的权限问题
- 《JAVA常用算法手册》 算法经典题 4.猴子吃桃
- Spark RDD
- Android Please ensure that adb is correctly located at问题解决
- Stanford 机器学习笔记 Week6 Advice for Applying Machine Learning
- 关于dubbo服务的xml配置文件报错的问题
- 欢迎使用CSDN-markdown编辑器
- poj 2367 Genealogical tree【拓扑排序】
- 初学JDBC