题目链接:##

点我

题目分析:##

树剖。将边权下放到下方点上(为什么要选深度更深的点?一个父亲可能对应多个儿子,但一个儿子只有一个父亲,即可以保证每个点只保存一条边权)成为经典点权+树剖裸题

注意链计算时不能把LCA算进去,其余细节较多,具体见代码。

代码:##

  1. #include<bits/stdc++.h>
  2. #define N (100000 + 5)
  3. #define inf (1000000000+7)
  4. using namespace std;
  5. inline int read() {
  6. int cnt = 0, f = 1; char c;
  7. c = getchar();
  8. while(!isdigit(c)) {
  9. if (c == '-') f = -f;
  10. c = getchar();
  11. }
  12. while(isdigit(c)) {
  13. cnt = cnt * 10 + c - '0';
  14. c = getchar();
  15. }
  16. return cnt * f;
  17. }
  18. int nxt[N * 2], first[N * 2], to[N * 2], w[N * 2], a[N], tot;
  19. int father[N], top[N], siz[N], dep[N], son[N], num[N], id[N], idx;
  20. int n, u, v, W, k;
  21. char opr[20];
  22. struct node{
  23. int l, r;
  24. long long cov, add, gmax;
  25. #define l(p) tree[p].l
  26. #define r(p) tree[p].r
  27. #define cov(p) tree[p].cov
  28. #define add(p) tree[p].add
  29. #define gmax(p) tree[p].gmax
  30. } tree[N * 4];
  31. struct edge{
  32. int u; int v;
  33. }e[N * 2];
  34. void Add(int x, int y, int z) {
  35. nxt[++tot] = first[x];
  36. first[x] = tot;
  37. to[tot] = y;
  38. w[tot] = z;
  39. }
  40. void dfs1(int cur, int fa) {
  41. father[cur] = fa; siz[cur] = 1; dep[cur] = dep[fa] + 1;
  42. for (register int i = first[cur]; i; i = nxt[i]) {
  43. int v = to[i];
  44. if(v != fa) {
  45. a[v] = w[i];
  46. dfs1(v, cur);
  47. siz[cur] += siz[v];
  48. if(siz[son[cur]] < siz[v]) son[cur] = v;
  49. }
  50. }
  51. }
  52. void dfs2(int cur, int tp) {
  53. top[cur] = tp; num[cur] = ++idx; id[idx] = cur;
  54. if (son[cur]) dfs2(son[cur], tp);
  55. for (register int i = first[cur]; i; i = nxt[i]) {
  56. int v = to[i];
  57. if (!num[v]) dfs2(v, v);
  58. }
  59. }
  60. void pushup(int p) {
  61. gmax(p) = max(gmax(p << 1), gmax(p << 1 | 1));
  62. }
  63. void pushcover(int p, int v){cov(p) = v; add(p) = 0; gmax(p) = v;}
  64. void pushadd(int p,int v){ add(p)+=v; gmax(p)+=v;}
  65. void pushdown(int p) {
  66. if (cov(p) >= 0) {
  67. pushcover(p<<1, cov(p)); pushcover(p<<1|1, cov(p)); cov(p) = -1;
  68. }
  69. if (add(p)) {
  70. pushadd(p<<1, add(p)); pushadd(p<<1|1, add(p)); add(p) = 0;
  71. }
  72. }
  73. void build_tree(int p, int l, int r) {
  74. l(p) = l; r(p) = r; cov(p) = -1;
  75. if(l == r) {
  76. gmax(p) = a[id[l]];
  77. // cout<<l<<" "<<r<<" "<<gmax(p)<<endl;
  78. return;
  79. }
  80. int mid = (l + r) >> 1;
  81. build_tree(p << 1, l, mid);
  82. build_tree(p << 1 | 1, mid + 1, r);
  83. pushup(p);
  84. }
  85. void debug(int u,int l,int r){
  86. if(l==r){
  87. cout<<id[l]<<" "<<gmax(u)<<endl;return;
  88. }int mid=(l+r)>>1;
  89. debug(u*2,l,mid);debug(u*2+1,mid+1,r);
  90. }
  91. void Cover(int p, int l, int r, int d) {
  92. if (l > r) return;
  93. if (l <= l(p) && r >= r(p)) {
  94. pushcover(p, d);
  95. return;
  96. }
  97. pushdown(p);
  98. int mid = (l(p) + r(p)) >> 1;
  99. if (l <= mid) Cover(p << 1, l, r, d);
  100. if (r > mid) Cover(p << 1 | 1, l, r, d);
  101. pushup(p);
  102. }
  103. void Modify(int p, int l, int r, int d) {
  104. if (l > r) return;
  105. if (l <= l(p) && r >= r(p)) {
  106. // if(cov(p) >= 0) {
  107. // cov(p) += d;
  108. // gmax(p) += d;
  109. // } else {
  110. // pushadd(p, d);
  111. // }
  112. pushadd(p, d);
  113. return;
  114. }
  115. pushdown(p);
  116. int mid = (l(p) + r(p)) >> 1;
  117. if (l <= mid) Modify(p << 1, l, r, d);
  118. if (r > mid) Modify(p << 1 | 1, l, r, d);
  119. pushup(p);
  120. }
  121. long long query(int p, int l, int r) {
  122. // cout<<p<<" "<<l(p)<<" "<<r(p)<<endl;
  123. if (l <= l(p) && r >= r(p)) return gmax(p);
  124. int mid = (l(p) + r(p)) >> 1;
  125. pushdown(p);
  126. //cout<<p<<endl;
  127. long long val = -inf;
  128. if (l <= mid) val = max (val, query(p << 1, l, r));
  129. if (r > mid) val = max(val, query(p << 1 | 1, l, r));
  130. return val;
  131. }
  132. void chain_cover(int u, int v, int d) {
  133. while (top[u] != top[v]) {
  134. if (dep[top[u]] < dep[top[v]]) swap(u, v);
  135. Cover(1, num[top[u]], num[u], d);
  136. u = father[top[u]];
  137. }
  138. if (dep[u] < dep[v]) swap(u, v);
  139. // if (u == v) Cover(1, num[v], num[u], d);
  140. Cover(1, num[v] + 1, num[u], d);
  141. }
  142. void chain_modify(int u, int v, int d) {
  143. while (top[u] != top[v]) {
  144. if (dep[top[u]] < dep[top[v]]) swap(u, v);
  145. Modify(1, num[top[u]], num[u], d);
  146. u = father[top[u]];
  147. }
  148. if (dep[u] < dep[v]) swap(u, v);
  149. // if (u == v) Modify(1, num[v], num[u], d);
  150. Modify(1, num[v] + 1, num[u], d);
  151. }
  152. long long chain_query(int u, int v) {
  153. long long ans = -inf;
  154. while (top[u] != top[v]) {//cout<<u<<endl;
  155. // cout<<top[u]<<" "<<top[v]<<endl;
  156. if (dep[top[u]] < dep[top[v]]) swap(u, v);
  157. // cout<<top[u]<<" "<<top[v]<<endl;
  158. // cout<<num[top[u]]<<" "<<num[u]<<endl;
  159. // cout<<query(1,num[top[u]],num[u])<<"###"<<endl;
  160. ans = max(ans, query(1, num[top[u]], num[u]));//cout<<"#";
  161. u = father[top[u]];
  162. // cout<<ans<<endl;
  163. }
  164. if (dep[u] < dep[v]) swap(u, v);
  165. ans = max(ans, query(1, num[v] + 1, num[u]));
  166. return ans;
  167. }
  168. void solve() {
  169. n = read();
  170. for (register int i = 1; i < n; i++) {
  171. u = read(); v = read(); W = read();
  172. e[i].u = u; e[i].v = v;
  173. Add(u, v, W); Add(v, u, W);
  174. }
  175. dfs1(1, 0); dfs2(1, 1);
  176. // for(int i=1;i<=n;i++)cout<<a[i]<<" ";cout<<endl;
  177. // for(int i=1;i<=n;i++)cout<<id[i]<<" ";cout<<endl;
  178. build_tree(1, 1, n);
  179. // debug(1,1,n);
  180. // cout<<"#"<<endl;
  181. for (;;) {
  182. scanf("%s", opr + 1);
  183. if (opr[1] == 'M') {
  184. u = read(); v = read();
  185. printf("%lld\n", chain_query(u, v));
  186. }
  187. if (opr[1] == 'C') {
  188. if (opr[2] == 'o') {
  189. u = read(); v = read(); W = read();
  190. chain_cover(u, v, W);
  191. }
  192. if (opr[2] == 'h') {
  193. u = read(); W = read();
  194. if (dep[e[u].u] < dep[e[u].v]) swap(e[u].u, e[u].v);
  195. // cout<<"nmsl"<<e[u].u<<" "<<e[u].v<<endl;
  196. // cout<<"##"<<num[e[u].u]<<"WWW"<<W<<endl;
  197. // chain_cover(num[e[u].u], num[e[u].v], W);
  198. Cover(1, num[e[u].u], num[e[u].u], W);
  199. }
  200. }
  201. if (opr[1] == 'A') {
  202. u = read(); v = read(); W = read();
  203. chain_modify(u, v, W);
  204. }
  205. if (opr[1] == 'S') break;
  206. // debug(1,1,n);cout<<endl;
  207. }
  208. return;
  209. }
  210. int main() {
  211. // freopen("input.in","r",stdin);
  212. solve();
  213. return 0;
  214. }

[洛谷P4315] 月下”毛景“树的更多相关文章

  1. 洛谷P4315 月下“毛景树”

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  2. 洛谷P4315 月下“毛景树”(树剖+线段树)

    传送门 woc这该死的码农题…… 把每一条边转化为它连接的两点中深度较深的那一个,然后就可以用树剖+线段树对路径进行修改了 然后顺便注意在上面这种转化之后,树剖的时候不能搞$LCA$ 然后是几个注意点 ...

  3. P4315 月下“毛景树”

    P4315 月下"毛景树" 题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬 ...

  4. P4315 月下“毛景树”(树链剖分)

    P4315 月下"毛景树"(树链剖分) 题面 简述: 边权转点权(在dfs1处转换) 把一条边权赋值在深度更深的上 需要实现对单边权的染色 , 路径边权的染色 , 路径边权的增加 ...

  5. P4315 月下“毛景树” (树链剖分+边剖分+区间覆盖+区间加+区间最大值)

    题目链接:https://www.luogu.org/problem/P4315 题目大意: 有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的.但是这棵“毛景树”有着神奇的魔力 ...

  6. P4315 月下“毛景树”[树剖]

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  7. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  8. 【BZOJ1984】月下“毛景树” 树链剖分+线段树

    [BZOJ1984]月下"毛景树" Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校 ...

  9. 【BZOJ-1984】月下“毛景树” 树链剖分

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1314  Solved: 416[Submit][Status][Discu ...

随机推荐

  1. 读取配置和动态配置(C方法)

    读取配置 无论何种配置文件,定义了配置文件之后,都统一使用系统提供的C方法(可以借助Config单词来帮助记忆)来读取已有的配置.用法:C('参数名称') 例如,读取当前的URL模式配置参数:$mod ...

  2. 基于深度学习的目标检测算法:SSD——常见的目标检测算法

    from:https://blog.csdn.net/u013989576/article/details/73439202 问题引入: 目前,常见的目标检测算法,如Faster R-CNN,存在着速 ...

  3. app测试点-1

    一.安全测试 1.软件权限 1)扣费风险:包括短信.拨打电话.连接网络等. 2)隐私泄露风险:包括访问手机信息.访问联系人信息等. 3)对App的输入有效性校验.认证.授权.数据加密等方面进行检测 4 ...

  4. CentOS 性能监控之nmon

    工具集: Nmon  性能数据收集分析工具Nmon analyser 性能数据分析工具,excel文件nmon_x86_sles10  Nmon在x86_sles10下二进制执行文件 nmon概述 n ...

  5. Java网络与多线程系列之1:实现一个简单的对象池

    前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...

  6. VijosP1250:分组背包

    背景 Wind设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了~ 描述 机器人们都想知道谁是最勇敢的,于是它们比赛搬运一些物品. 它们到了一个仓库,里面有n个物品,每个物品都有一个价 ...

  7. maven+eclpse+jmeter+jenkis

    1.maven配置:http://www.cnblogs.com/AlanLee/p/6133189.html 2.在eclipse中创建maven项目:https://jingyan.baidu.c ...

  8. linux 中C语言便于调试的宏定义编写及 __FILE__,__FUNCTION__, __LINE__参数使用

    转自:http://blog.csdn.net/edonlii/article/details/8491342/ 在linux编程中,当文件数量变的众多之后,使用gdb调试就是一场灾难.因此在程序中加 ...

  9. ubuntu在recovery模式下更改用户密码

    http://www.jb51.net/os/Ubuntu/164636.html 1, restart 2, Hold down shift key / press and hold 3, sele ...

  10. 一步步实现 Prism + MEF(二)--- 绑定命令

    Prism程序集为我们提供了DelegateCommand命令,使用该命令可实现窗口直接绑定.第一步:在ViewModel中定义一个DelegateCommand属性. public Delegate ...