一看就知道 可以LCA判断做 也可以树链剖分拿头暴力

然而快速读入和线段树维护区间会T70 于是只能LCA?

线段树的常数不小 于是需要另外一种办法来进行区间加减和查询区间和 就是使用树状数组

这个题的代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<vector>
  6. #include<cstring>
  7. using namespace std;
  8. #define pb push_back
  9.  
  10. int n , qn ;
  11. vector<int > q [100050] ;
  12. int top[100050] , fa[100050] , deep[100050] , num[100050] , p[100050] , fp[100050] , son[100050] , pos ;
  13.  
  14. inline int read()
  15. {
  16. int x=0;char ch=getchar();
  17. while(ch<'0'||ch>'9')ch=getchar();
  18. while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
  19. return x;
  20. }
  21.  
  22. ///----------
  23.  
  24. int c[100050] ;
  25. int d[100050] ;
  26. int lowbit(int x) {
  27. return (x & (-x)) ;
  28. }
  29. void add(int c[] , int x ,int val) {
  30. while(x <= n+5) {
  31. c[x] += val ; x += lowbit(x) ;
  32. }
  33. }
  34. int sum(int c[] , int x) {
  35. int res = 0 ;
  36. while(x > 0) {
  37. res += c[x] ;
  38. x -= lowbit(x) ;
  39. }
  40. return res ;
  41. }
  42. void add(int l , int r , int val) {
  43. add(c , l , val) ; add(d , l , l * val) ;
  44. add(c , r+1 , -val ) ; add(d , r + 1 , -val * (r+1)) ;
  45. }
  46. int sum(int x) {
  47. return (x + 1) * sum(c , x) - sum(d , x) ;
  48. }
  49. int sum(int l , int r) {
  50. return sum(r) - sum(l - 1) ;
  51. }
  52.  
  53. ///----------
  54.  
  55. void dfs1(int u , int pre , int d) {
  56. deep[u] = d ;
  57. fa[u] = pre ;
  58. num[u] = 1 ;
  59. for(int i = 0 ; i < q[u].size() ; i ++ ) {
  60. int v = q[u][i] ;
  61. if(v != pre) {
  62. dfs1(v , u , d+1) ;
  63. num[u] += num[v] ;
  64. if(son[u] == -1 || num[v] > num[son[u]]) {
  65. son[u] = v ;
  66. }
  67. }
  68. }
  69. }
  70. void getpos(int u , int sp) {
  71. top[u] = sp ;
  72. p[u] = pos ++ ;
  73. fp[p[u]] = u ;
  74. if(son[u] == -1) return ;
  75. getpos(son[u] , sp) ;
  76. for(int i = 0 ; i < q[u].size() ; i ++ ) {
  77. int v = q[u][i] ;
  78. if(v != son[u] && v != fa[u]) {
  79. getpos(v , v) ;
  80. }
  81. }
  82. }
  83. void chang(int u , int v , int val) {
  84. int f1 = top[u] , f2 = top[v] ;
  85. int tmp = 0 ;
  86. while(f1 != f2) {
  87. if(deep[f1] < deep[f2]) {
  88. swap(f1 , f2) ; swap(u , v) ;
  89. }
  90. add(p[f1] , p[u] , val) ;
  91. u = fa[f1] ;
  92. f1 = top[u] ;
  93. }
  94. if(deep[u] > deep[v]) swap(u , v) ;
  95. add(p[u] , p[v] , val) ;
  96. }
  97. int que(int u , int v) {
  98. int f1 = top[u] , f2 = top[v] ;
  99. int tmp = 0 ;
  100. while(f1 != f2) {
  101. if(deep[f1] < deep[f2]) {
  102. swap(f1 , f2) ; swap(u , v) ;
  103. }
  104. tmp += sum(p[f1] , p[u]) ;
  105. u = fa[f1] ;
  106. f1 = top[u] ;
  107. }
  108. if(deep[u] > deep[v]) swap(u , v) ;
  109. tmp += sum(p[u] , p[v]) ;
  110. return tmp ;
  111. }
  112.  
  113. int main () {
  114. n = read() ;
  115. qn = read() ;
  116. for(int i = 2 ; i <= n ; i ++ ) {
  117. int z ; z = read() ;
  118. q[z].pb(i) ; q[i].pb(z) ;
  119. }
  120. memset(son , -1 , sizeof(son)) ;
  121. pos = 1 ;
  122. dfs1(1,0,0) ;
  123. getpos(1 , 1) ;
  124. while(qn -- ) {
  125. int aa , bb , cc ;
  126. aa = read() ; bb = read() ; cc = read() ;
  127.  
  128. int ans = 0 ;
  129.  
  130. chang(aa,bb,1) ;
  131. ans = max(que(bb,cc) , ans) ;
  132. chang(aa,bb,-1) ;
  133.  
  134. chang(aa,cc,1) ;
  135. ans = max(que(bb,cc) , ans) ;
  136. chang(aa,cc,-1) ;
  137.  
  138. chang(aa,bb,1) ;
  139. ans = max(que(aa,cc) , ans) ;
  140. chang(aa,bb,-1) ;
  141.  
  142. printf("%d\n" , ans) ;
  143. }
  144. }

其中的树状数组 拿两个数组来分别维护 具体代码

  1. int c[100050] ;
  2. int d[100050] ;
  3. int lowbit(int x) {
  4. return (x & (-x)) ;
  5. }
  6. void add(int c[] , int x ,int val) {
  7. while(x <= n+5) {
  8. c[x] += val ; x += lowbit(x) ;
  9. }
  10. }
  11. int sum(int c[] , int x) {
  12. int res = 0 ;
  13. while(x > 0) {
  14. res += c[x] ;
  15. x -= lowbit(x) ;
  16. }
  17. return res ;
  18. }
  19. void add(int l , int r , int val) {
  20. add(c , l , val) ; add(d , l , l * val) ;
  21. add(c , r+1 , -val ) ; add(d , r + 1 , -val * (r+1)) ;
  22. }
  23. int sum(int x) {
  24. return (x + 1) * sum(c , x) - sum(d , x) ;
  25. }
  26. int sum(int l , int r) {
  27. return sum(r) - sum(l - 1) ;
  28. }

树状数组天下无敌TAT 于是又上网学习了新姿势 我有姿势我自豪

树状数组单点修改 + 区间查询max

  1. int num[5000] ;
  2. int c[5000] ;
  3. int n ;
  4. int lowbit(int x)
  5. {
  6. return x & (-x);
  7. }
  8. void updata(int x)
  9. {
  10. int lx, i;
  11. while (x <= n)
  12. {
  13. c[x] = num[x];
  14. lx = lowbit(x);
  15. for (i=1; i<lx; i<<=1)
  16. c[x] = max(c[x], c[x-i]);
  17. x += lowbit(x);
  18. }
  19. }
  20. int query(int L, int R)
  21. {
  22. int ans = 0;
  23. while (R >= L)
  24. {
  25. ans = max(num[R], ans);
  26. R --;
  27. for (; R-lowbit(R) >= L; R -= lowbit(R))
  28. ans = max(c[R], ans);
  29. }
  30. return ans;
  31. }

以及这里还有...矩形增减 + 矩形查询和的黑科技。。。

http://blog.csdn.net/lawrence_jang/article/details/8054173

Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间的更多相关文章

  1. Codeforces Round #425 (Div. 2) D.Misha, Grisha and Underground

    我奇特的脑回路的做法就是 树链剖分 + 树状数组 树状数组是那种 区间修改,区间求和,还有回溯的 当我看到别人写的是lca,直接讨论时,感觉自己的智商收到了碾压... #include<cmat ...

  2. hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...

  3. Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

  4. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  5. 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...

  6. bzoj 2819 Nim dfn序+树状数组维护区间异或值

    题目大意 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...

  7. Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组

    Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...

  8. Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分

    D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...

  9. Codeforces Round #425 (Div. 2) - D

    题目链接:http://codeforces.com/contest/832/problem/D 题意:给定一棵n个点的树,然后给你q个询问,每个询问为三元组(a,b,c),问你从这三个点中选取一个作 ...

随机推荐

  1. 如何将大数据保存到 MySql 数据库

    1. 什么是大数据 1. 所谓大数据, 就是大的字节数据,或大的字符数据. 2. 标准 SQL 中提供了如下类型来保存大数据类型: 字节数据类型: tinyblob(256B), blob(64K), ...

  2. 一、Nuxt简介

    1.Nuxt是什么    Nuxt.js是基于vue的服务器端渲染框架,常用来做SSR(服务器端渲染)   2.为什么用Nuxt    Vue开发的SPA(单页应用)不利于搜索引擎的SEO优化   3 ...

  3. 父标签浮动(float)“塌陷”问题

    浮动“塌陷” float参见: http://www.cnblogs.com/bigtreei/p/8110090.html http://www.w3school.com.cn/css/css_po ...

  4. python cookbook第三版学习笔记二十一:利用装饰器强制函数上的类型检查

    在演示实际代码前,先说明我们的目标:能对函数参数类型进行断言,类似下面这样: @typeassert(int, int) ... def add(x, y): ...     return x + y ...

  5. (4.13)SQL Server profile使用、数据库优化引擎顾问使用

    SQL Server profile使用技巧 介绍 经常会有人问profile工具该怎么使用?有没有方法获取性能差的sql的问题.自从转mysql我自己也差不多2年没有使用profile,忽然prof ...

  6. Longest Common Prefix -最长公共前缀

    问题:链接 Write a function to find the longest common prefix string amongst an array of strings. 解答: 注意 ...

  7. JavaWeb—过滤器Filter

    1.Filter简介 Filter称之为过滤器,是用来做一些拦截的任务.比如客户端请求服务器的某个资源时(可以是Servlet.JSP.HTML等等),我们可以拦截.当服务器返回资源给客户端的时候,我 ...

  8. mysql启动报错“NET HELPMSG 3534“的解决办法

    原因: mysql安装步骤错误,从mysql5.7.6开始,mysql需要这样安装: mysqld --initialize-insecure或者mysqld --initialize mysqld ...

  9. PictureBox 双缓冲防止闪屏

    Bitmap bm = new Bitmap(this.pbTraffic.Image); BufferedGraphicsContext current = BufferedGraphicsMana ...

  10. 前端 css续

    CSS选择器 1.标签选择器 为类型标签设置样式例如:<div>.<a>.等标签设置一个样式,代码如下: <style> /*标签选择器,找到所有的标签应用以下样式 ...