[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名学生,方阵的行数为 ...
随机推荐
- @import与link方式的区别
1. 老祖宗的差别.link属于XHTML标签,而@import完全是CSS提供的一种方式. link标签除了可以加载CSS外,还可以做很多其它的事情,比如定义RSS,定义rel连接属性等,@impo ...
- 使用VC++编写QQ群发器,MFC做UI
由于公司业务需要,QQ群发器经常被用来发送QQ广告,购买的QQ群发器不好用不说,而且是按机器收费的,有些功能还不能修改. 所以公司派我来开发一款自己的QQ群发器,我给群发器取名叫做飞速群发器,用来给软 ...
- leetcode_Stone Game_dp_思维
Alex和Lee玩游戏,共有偶数堆石头,石头总数为奇数,两人每次要么拿第一堆,要么拿最后一堆,两人以最优策略拿石堆(一次拿走完整的一堆),Alex先手,Alex赢返回True,否则返回False. 思 ...
- JAVA——不简单的fianl关键字
protected用来修饰 域,代表域的访问权限是:包权限 或者 不同包,但是是子类 : final 修饰常量只要是该常量代入的计算式,在编译时期,就会被执行计算,以减轻运行时的负担.(只对基本数据类 ...
- day25-2 OSI协议和socket抽象层
目录 OSI协议 物理层 数据链路层 以太网协议 Mac地址 广播地址 网络层 获取对方Mac地址(ARP协议) 传输层 TCP协议 UDP协议 应用层 socket抽象层 OSI协议 互联网的本质就 ...
- OpenMP入门教程(一)
什么是OpenMP Open Multi-Processing的缩写,是一个应用程序接口(API),可用于显式指导多线程.共享内存的并行性. 在项目程序已经完成好的情况下不需要大幅度的修改源代码,只需 ...
- cmanformat - 不是命令啦,是个演示文件
描述 DESCRIPTION cmanformat 是 man pages 格式的演示文件. 由于系统不同会有差异.在 XWindow 下会好些. __________________________ ...
- 笔试算法题(06):最大连续子数组和 & 二叉树路径和值
出题:预先输入一个整型数组,数组中有正数也有负数:数组中连续一个或者多个整数组成一个子数组,每个子数组有一个和:求所有子数组中和的最大值,要求时间复杂度O(n): 分析: 时间复杂度为线性表明只允许一 ...
- Python 字符编码-文件处理
.read #读取所有内容,光标移动到文件末尾.readable #判断文件是否可读.readline #读取一行内容,光标移动到第二行首部.readlines #读取每一行内容,存放于列表中.wri ...
- Centos6.8 安装mongo3.6以及权限配置和开启外网链接
目录 安装环境和版本说明,以及参考文档链接 安装MongoDB数据库 运行MongoDB数据库 删除卸载MongoDB 配置MongoDB管理员用户 修改配置文件,允许外网链接 安装配置完成,使用Ro ...