传送门

需要把一条路径上除了终点外的所有数都 + 1,

比如,给路径 s - t 上的权值 + 1,可以先求 x = lca(s,t)

类似数列上差分的思路,可以给 s 和 f[t] 的权值 + 1,给 x 和 f[x] 的权值 - 1

最后统计以每个节点为根的子树的和,则每个节点的权值就是子树的权值。

——代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4.  
  5. const int MAXN = ;
  6. int n, cnt;
  7. int a[MAXN], head[MAXN], to[MAXN << ], next[MAXN << ], deep[MAXN], f[MAXN][], val[MAXN];
  8.  
  9. inline int read()
  10. {
  11. int x = , f = ;
  12. char c = getchar();
  13. for(; !isdigit(c); c = getchar()) if(c == '-') f = -;
  14. for(; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
  15. return x * f;
  16. }
  17.  
  18. inline void add(int x, int y)
  19. {
  20. to[cnt] = y;
  21. next[cnt] = head[x];
  22. head[x] = cnt++;
  23. }
  24.  
  25. inline void swap(int &x, int &y) { x ^= y ^= x ^= y; }
  26.  
  27. inline void dfs(int u)
  28. {
  29. int i, v;
  30. deep[u] = deep[f[u][]] + ;
  31. for(i = ; f[u][i]; i++) f[u][i + ] = f[f[u][i]][i];
  32. for(i = head[u]; i != -; i = next[i])
  33. {
  34. v = to[i];
  35. if(!deep[v]) f[v][] = u, dfs(v);
  36. }
  37. }
  38.  
  39. inline int lca(int x, int y)
  40. {
  41. int i;
  42. if(deep[x] < deep[y]) swap(x, y);
  43. for(i = ; i >= ; i--)
  44. if(deep[f[x][i]] >= deep[y])
  45. x = f[x][i];
  46. if(x == y) return x;
  47. for(i = ; i >= ; i--)
  48. if(f[x][i] != f[y][i])
  49. x = f[x][i], y = f[y][i];
  50. return f[x][];
  51. }
  52.  
  53. inline void dfs1(int u)
  54. {
  55. int i, v;
  56. for(i = head[u]; i != -; i = next[i])
  57. {
  58. v = to[i];
  59. if(v != f[u][]) dfs1(v), val[u] += val[v];
  60. }
  61. }
  62.  
  63. int main()
  64. {
  65. int i, x, y, z;
  66. n = read();
  67. memset(head, -, sizeof(head));
  68. for(i = ; i <= n; i++) a[i] = read();
  69. for(i = ; i < n; i++)
  70. {
  71. x = read();
  72. y = read();
  73. add(x, y);
  74. add(y, x);
  75. }
  76. dfs();
  77. for(i = ; i <= n; i++)
  78. {
  79. x = a[i - ];
  80. y = a[i];
  81. z = lca(x, y);
  82. val[z]--, val[f[z][]]--;
  83. val[x]++, val[f[y][]]++;
  84. }
  85. dfs1();
  86. for(i = ; i <= n; i++) printf("%d\n", val[i]);
  87. return ;
  88. }

[luoguP3258] [JLOI2014]松鼠的新家(lca + 树上差分)的更多相关文章

  1. luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)

    P3258 [JLOI2014]松鼠的新家  题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...

  2. [JLOI2014] 松鼠的新家 (lca/树上差分)

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

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

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

  4. 洛谷P3258 [JLOI2014]松鼠的新家(树上差分+树剖)

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

  5. BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】

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

  6. bzoj3631: [JLOI2014]松鼠的新家(树上差分)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 题目大意:给定含有n个顶点的树,给定走遍整棵树顺序的序列a[1],a[2],a[3 ...

  7. [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2350  Solved: 1212[Submit][Sta ...

  8. 【bzoj3631】[JLOI2014]松鼠的新家 LCA+差分数组

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀请小熊维尼前来 ...

  9. luoguP3258 [JLOI2014]松鼠的新家

    树上差分 树上差分分析 使点x到点y的路径上(链上),全加上一个值,可以选择使用树上差分(不用线段树乱搞.... 首先,和普通的差分一样,要有一个tag.然而,对于一个结点,我们需要求出它全部儿子的t ...

随机推荐

  1. Win10新机的安装与配置

    一.快捷键 打开Chrome上次关闭的所有标签页:Ctrl-Shift-T 二.问题解决 1. 右键取得管理员权限 https://www.tenforums.com/tutorials/3841-a ...

  2. Oracle 十大SQL语句

    oracle数据库十大SQL语句             操作对象(object) /*创建对象 table,view,procedure,trigger*/ create object object ...

  3. Spring Boot学到的内容

    Hello World:了解程序入口(创建启动类) Web程序:写Controller类(@RestController),写Controller方法(@GetMapping),maven依赖spri ...

  4. iOS 二维码的生成 QREncoder

    生成二维码: 在生成二维码的库中QREncoder最为常见,但是由于中文字符的特殊性,生成中文的时候有时会出现一定的错误,所以建议使用libqrencode,是一个纯C编写的类库. 以libqrenc ...

  5. JAVA设计模式--Strategy

    策略模式就是说当我进行比较大小的时候定义一个策略的比较器Comparator,然后由具体的比较策略来决定用什么量来比较大小.

  6. [Python筆記] 將 Pandas 的 Dataframe 寫入 Sqlite3

    使用 pandas.io 寫入 Sqlite import sqlite3 as lite from pandas.io import sql import pandas as pd 依照 if_ex ...

  7. dmesg -检测和控制内核环缓冲

    NAME dmesg - print or control the kernel ring buffer 总览 dmesg [ -c ] [ -n 级别 ] [ -s 缓冲区大小 ] 描述 dmesg ...

  8. iview table icon dorpdown html页面级别vue组件 #vuez#

    iview table icon dorpdown html页面级别vue组件 <!DOCTYPE html> <html> <head> <meta cha ...

  9. GCC、g++编译器和gcc编译器的区别

    GCC:(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器.它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分. gcc:GNU的C语 ...

  10. 【软件构造】第三章第四节 面向对象编程OOP

    第三章第四节 面向对象编程OOP 本节讲学习ADT的具体实现技术:OOP Outline OOP的基本概念 对象 类 接口 抽象类 OOP的不同特征 封装 继承与重写(override) 多态与重载( ...