题意:有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(动态开点线段树+合并)的更多相关文章

  1. [Vani有约会]雨天的尾巴——树上差分+动态开点线段树合并

    题目描述 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮. 然后深绘里想知道,当所 ...

  2. codeforces 893F - Physical Education Lessons 动态开点线段树合并

    https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...

  3. [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)

    题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...

  4. [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...

  5. 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化

    4636: 蒟蒻的数列 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 247  Solved: 113[Submit][Status][Discuss ...

  6. codeforces 915E - Physical Education Lessons 动态开点线段树

    题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...

  7. CF915E Physical Education Lessons 动态开点线段树

    题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...

  8. 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)

    题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  9. NOIP2017 列队——动态开点线段树

    Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为  ...

随机推荐

  1. ssm基础配置

    1.导包 <dependencies> <dependency> <groupId>org.springframework</groupId> < ...

  2. Web前端深思

    WEB视图层技术从最初刀耕火种的时代到如今技术框架丛生,其中的感受只有经历过才知道.但到目前为止前端领域还只是整个IT行业比较边缘化的分支,因为目前的前端coder大多都还停留在视图层的处理上,利用前 ...

  3. php(一)

    PHP (Hypertext preprocessor 超文本预处理器) 1.环境工具 Xampp等工具 2.apache配置 默认的Apache路径是  c:/xampp/apache 文件夹 可以 ...

  4. Android应用开发细节点

    1.如果handler是在主线程声明,就属于主线程,handleMessage属于引用handler的那个线程:2.ByteArrayOutputStream/ByteArrayInputStream ...

  5. springmvc 获取数组

    spingmvc 获取数据有这几种方式:1.通过HttpRequestServlet的方法获取数据.2.form表单传递对象字段,springmvc自动获取.3.ajax 请求通过注解的方式直接获取数 ...

  6. oracle 安装,启动 ,plsql 连接

    1.下载oracle 服务器端,正常安装,在选择桌面类或者是服务器类的时候选择服务器类. 2.下载oracle 客户端解压版 下载地址   链接:https://pan.baidu.com/s/1mi ...

  7. Asp.Net 设计模式 之 “特殊”的单例模式

    特殊的单例模式 要点在这里,提前预览: public SingleDemo() { name = "yy"; age = 20; //特殊的单例,this指代得失当前的Single ...

  8. Vue 拦截器的使用

    拦截器 可以全局进行拦截器设置.拦截器在发送请求前或响应返回时做一些特殊的处理. 拦截器的注册 Vue.http.interceptors.push({ request: function ( req ...

  9. Divide and Conquer_1.最大连续子数组

    给定一个数组,求它的一个子数组,使其求和最大. 这个问题的应用:给定一只股票很多天的价格,计算从哪天买进哪天卖出能获得最大利润. 给定 prices:100   113   98   87   65  ...

  10. Python:webshell 跳板机审计服务器

    1.修改paramiko源码包实现 https://github.com/paramiko/paramiko/tree/1.10.1 下载源码包 unzip paramiko-1.10.1.zip p ...