[HDU5709]Claris Loves Painting(动态开点线段树+合并)
题意:有n(<=1e5)个点的树,每个点都有颜色(颜色可能重复),有m(<=1e5)个询问,每次询问(x,d)问在x的子树中,与x的距离不超过d的节点有多少种不同的颜色。强制要求在线。
分析:
Part A:先考虑颜色不重复的
如果我们能把每个节点的子树信息建成以深度作为下标的线段树,那么就能很简单地应付查询了
这个信息也很明显,就是下标表示深度,权值表示该深度的节点有多少种不同颜色(注意我们先考虑颜色没有重复的)
那么我们可以先对每个节点自己建一个权值线段树,把自己对应深度的那个位置放个1,其它位置放0
从底向上合并线段树,那么我们就可以得到表示每个节点子树的线段树辣!
但是每个点暴力开线段树是肯定MLE的
这个时候我们发现我们建的权值线段树只有一个位置是1,其它都是0,受到主席树节约空间的启发,我们最初建线段树的时候只需要建logn的空间(也就是一边)
然后合并的时候也类似主席树的那样,有信息更新的节点就重新开个节点来表示,否则直接利用原来建过的节点
分析一下复杂度,对于n个点,初始建logn的线段树,是O(nlogn)的
那合并呢?考虑均摊,对于有k个值不是0的一颗线段树,均摊地认为它节点个数是Ck的,而不是Cklogn,那么一路合并上去,就是O(nlogn)的时间(虽然常数有点大)
ok这都是可以接受的,但是很显然我们这种做法对于同种颜色会重复叠加,那么如何处理呢?
Part B:
在处理序列里这种颜色重复问题时候,以前都是弄一个pre[x]表示该位置前面的一个同颜色的节点的位置,但这在树上就不适用了,但是可以类比,树上的顺序关系肯定就是深度的大小;而且这题需要合并,那就不能直接用数组记录,需要用线段树处理合并。
方法是对每个点再建一个线段树,下标表示颜色(1..n),权值表示该颜色在当前子树中出现的最小深度是多少
同样从叶子节点开始向上合并,合并的时候也是同样将两棵树一直合并到叶子节点,两边取个min就行了
关键是这是怎样修正我们的答案的呢?
我们对这第二棵线段树维护到叶节点的时候,这说明我们在合并我们当前的第一棵颜色的时候,当前颜色多算了,那么就把这个max的深度作为下标在第一棵线段树中减掉
那么减掉多少呢?
实际上就是减1,因为自底向上,一直保持这样的操作,那么每次多加的次数一定就是1,所以减掉的次数也是1
注意更新第一棵线段树中的值的时候,也要动态开辟新的节点
复杂度也是O(nlogn)的
因为每次修改/合并都要开辟logn的节点,所以整个需要的空间大概是2*m*(3*logn)
这样的空间是不会爆的,当然也可以类似主席树的那种对下标进行重回收(还记得大明湖畔的zoj2112吗)
[HDU5709]Claris Loves Painting(动态开点线段树+合并)的更多相关文章
- [Vani有约会]雨天的尾巴——树上差分+动态开点线段树合并
题目描述 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮. 然后深绘里想知道,当所 ...
- codeforces 893F - Physical Education Lessons 动态开点线段树合并
https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...
- [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)
题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
4636: 蒟蒻的数列 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 247 Solved: 113[Submit][Status][Discuss ...
- codeforces 915E - Physical Education Lessons 动态开点线段树
题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...
- CF915E Physical Education Lessons 动态开点线段树
题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- NOIP2017 列队——动态开点线段树
Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为 ...
随机推荐
- 解决 图片在div中等比例缩放问题 (未解决:图片比例小于盒子模型时不会自动填充)
如题,该方案仅支持对图片等比例缩放.本文附件地址:https://files.cnblogs.com/files/john69-/background-Img.rar <!DOCTYPE htm ...
- Asp.Net中调用存储过程并返回输出参数
/// <summary> /// 调用存储过程返回参数 /// </summary> /// <param name="orderId">&l ...
- Android习惯--Activity启动方法
public void Text extends Activity{ public void static actionStart(Context context, int i, String str ...
- Farseer.net轻量级ORM开源框架 V1.x 入门篇:存储过程实体类映射
导航 目 录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:视图的数据操作 下一篇:Farseer.net轻量级ORM开源 ...
- [Windows Server 2008] 404错误设置方法
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:如何设置4 ...
- JPA调用存储过程
@Transactional public BasAccount findByAccount(String account) { System.out.println(account); Query ...
- Python list列表的常用操作方法
本文主要介绍了Python中列表(List)的详解操作方法,包含创建.访问.删除.排序.切片,乘等操作方法 1.创建列表:把逗号分隔的不同的数据项使用方括号括起来 list = [1,2,3,'Jam ...
- ipv6工具类
package mapreduce.nat; import java.math.BigDecimal; import java.math.BigInteger; import java.net.Ine ...
- shell learning note
shell learning note MAIN="/usr/local/" # 变量大写 STATUS="$MAIN/status" # 美元符加字符串是 ...
- BZOJ 2502 Luogu P4843 清理雪道 最小流
题意: 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机 ...