题目描述

松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。

松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。

因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

题目分析

树剖,树状数组维护

相邻两个计划点之间的点权++,第2~n个计划点点权-1。

Code

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4.  
  5. const int MAXN = + ;
  6.  
  7. struct Edge {
  8. int nxt;
  9. int to;
  10. } l[MAXN<<];
  11.  
  12. int n,root;
  13. int head[MAXN],cnt;
  14. int deep[MAXN],fa[MAXN],siz[MAXN],heavy[MAXN];
  15. int id[MAXN],tot;
  16. int a[MAXN],c[MAXN],top[MAXN];
  17.  
  18. inline void add(int x,int y) {
  19. cnt++;
  20. l[cnt].nxt = head[x];
  21. l[cnt].to = y;
  22. head[x] = cnt;
  23. return;
  24. }
  25.  
  26. void dfs1(int x,int from) {
  27. deep[x] = deep[from] + ;
  28. fa[x] = from;
  29. int tmp = ;
  30. siz[x] = ;
  31. for(int i = head[x];i;i = l[i].nxt) {
  32. if(l[i].to == from) continue;
  33. dfs1(l[i].to,x);
  34. siz[x] += siz[l[i].to];
  35. if(siz[l[i].to] > tmp) {
  36. tmp = siz[l[i].to];
  37. heavy[x] = l[i].to;
  38. }
  39. }
  40. return;
  41. }
  42.  
  43. void dfs2(int x,int tp,int from) {
  44. id[x] = ++tot;
  45. top[x] = tp;
  46. if(!heavy[x]) return;
  47. dfs2(heavy[x],tp,x);
  48. for(int i = head[x];i;i = l[i].nxt) {
  49. if(l[i].to == from || l[i].to == heavy[x]) continue;
  50. dfs2(l[i].to,l[i].to,x);
  51. }
  52. return;
  53. }
  54.  
  55. inline int lowbit(int x) {
  56. return x & (-x);
  57. }
  58.  
  59. inline void modify(int x,int y,int v) {
  60. for(int i = x;i <= n;i += lowbit(i)) c[i]+=v;
  61. for(int i = y+;i <= n;i += lowbit(i)) c[i]-=v;
  62. return;
  63. }
  64.  
  65. inline int query(int x) {
  66. int res = ;
  67. for(int i = x;i;i -= lowbit(i)) res += c[i];
  68. return res;
  69. }
  70.  
  71. inline void wayadd(int x,int y,int v) {
  72. while(top[x] != top[y]) {
  73. if(deep[top[x]] < deep[top[y]]) swap(x,y);
  74. modify(id[top[x]],id[x],v);
  75. x = fa[top[x]];
  76. }
  77. if(deep[x] > deep[y]) swap(x,y);
  78. modify(id[x],id[y],v);
  79. return;
  80. }
  81.  
  82. int main() {
  83. scanf("%d",&n);
  84. for(int i = ;i <= n;i++) {
  85. scanf("%d",&a[i]);
  86. }
  87. root = a[];
  88. int x,y;
  89. for(int i = ;i < n;i++) {
  90. scanf("%d%d",&x,&y);
  91. add(x,y);add(y,x);
  92. }
  93. dfs1(root,);
  94. dfs2(root,root,);
  95. for(int i = ;i < n;i++) {
  96. wayadd(a[i],a[i+],);
  97. wayadd(a[i+],a[i+],-);
  98. }
  99. for(int i = ;i <= n;i++) {
  100. printf("%d\n",query(id[i]));
  101. }
  102. return ;
  103. }

[Luogu] P3258 [JLOI2014]松鼠的新家的更多相关文章

  1. 【luogu P3258 [JLOI2014]松鼠的新家】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3258 谁说树剖过不去会RE呢? 我今天就是要强行树剖了 树剖强艹 #include <cstdio&g ...

  2. P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...

  3. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  4. 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家

    [题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...

  5. [Luogu 3258] JLOI2014 松鼠的新家

    [Luogu 3258] JLOI2014 松鼠的新家 LCA + 树上差分. 我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分. qwq不讲了不讲了,贴代码. #i ...

  6. 洛谷P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  7. P3258[JLOI2014]松鼠的新家(LCA 树上差分)

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  8. 洛谷 P3258 [JLOI2014]松鼠的新家 题解

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  9. 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...

随机推荐

  1. Vijos 1193 扫雷 【动态规划】

    扫雷 描述 相信大家都玩过扫雷的游戏.那是在一个n*n的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了,“余”任过流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它 ...

  2. 写一个简单的Makefile

    all: osx .PHONY: osx linux run osx: kale.dylib linux : kale.so run: kale.bin CC = gcc OBJECTS = $(pa ...

  3. Linux/Android——Input系统之frameworks层InputManagerService (六)【转】

    本文转载自:http://blog.csdn.net/u013491946/article/details/72638954 版权声明:免责声明: 本人在此发文(包括但不限于汉字.拼音.拉丁字母)均为 ...

  4. 【JSOI 2011】 分特产

    [题目链接] 点击打开链接 [算法] 考虑求每个人可以不分的方案 那么,对于每件物品,我们把它分成n份,每一份对应分给每一个人,有C(a[i]+n-1,m-1)种方案,而总方案数就是每种 物品方案数的 ...

  5. POJ1264 SCUD Busters 凸包

    POJ1264 有m个国家(m<=20)对每个国家给定n个城镇 这个国家的围墙是保证围住n个城镇的周长最短的多边形 必然是凸包 进行若干次导弹发射 落到一个国家内则国家被破坏 最后回答总共有多少 ...

  6. P3402 【模板】可持久化并查集

    传送门 //minamoto #include<bits/stdc++.h> using namespace std; #define getc() (p1==p2&&(p ...

  7. python实现汉诺塔程序

    # 汉诺塔思想笔记# 认识汉诺塔的目标:把A柱子上的N个盘子移动到C柱子# 递归的思想就是把这个目标分解成三个子目标# 子目标1:将前n-1个盘子从a移动到b上# 子目标2:将最底下的最后一个盘子从a ...

  8. 源码阅读之HashMap(JDK8)

    概述 HashMap根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的. HashMap最多只允许一条记录的键为null,允许多条记录 ...

  9. 为WebSphere Application Server v8.5安装并配置JDK7

    IBM WebSphere Application Server v8.5可以同时支持不同版本的JDK共存,并且可以通过命令设置概要文件所使用的JDK版本.WAS8.5默认安装JDK6,如果要使用JD ...

  10. CF897C Nephren gives a riddle

    思路: 递归. 比赛的时候脑抽了len[]没算够,wa了几次. 实现: #include <bits/stdc++.h> using namespace std; using ll = l ...