近期在强化知识点深度。发现树链剖分不是非常会写了。

回想一下改动操作:

若两个点在同一条链上,则直接改动这段区间。

若不在同一条链上,改动深度较大的点到其链顶端的区间,同一时候将这个点变为他所在链顶端的父亲,循环操作直到这两个点在同一条链上。就能够用上一种方法了。

没实用LCA写是由于曾经被坑过,不但没有这样的方法好写。效率也不太让人惬意。

主要是对另外一种情况怎样写有所遗忘。写道模版再给自己提个醒。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<string.h>
  5. #include<math.h>
  6. #include<algorithm>
  7. #include<vector>
  8. #include<queue>
  9. using namespace std;
  10. #define MAXN 50005
  11. int n,m,q;
  12. vector<int> map[MAXN];
  13. int size[MAXN],fa[MAXN],son[MAXN],val[MAXN],tid[MAXN],_tid[MAXN],dep[MAXN],top[MAXN];
  14. int cnt;
  15. struct node
  16. {
  17. int l,r,val;
  18. }tree[MAXN<<2];
  19. void dfs1(int s,int f,int d)
  20. {
  21. size[s]=1;
  22. fa[s]=f;
  23. dep[s]=d;
  24. int len=map[s].size();
  25. for(int i=0;i<len;i++)
  26. {
  27. int e=map[s][i];
  28. if(e==f)continue;
  29. dfs1(e,s,d+1);
  30. size[s]+=size[e];
  31. if(son[s]==0)
  32. son[s]=e;
  33. else if(size[son[s]]<size[e])
  34. son[s]=e;
  35. }
  36. }
  37. void dfs2(int s,int t)
  38. {
  39. tid[s]=++cnt;
  40. _tid[cnt]=s;
  41. top[s]=t;
  42. if(son[s]!=0)
  43. dfs2(son[s],t);
  44. int len=map[s].size();
  45. for(int i=0;i<len;i++)
  46. {
  47. int e=map[s][i];
  48. if(e!=fa[s] && e!=son[s])
  49. dfs2(e,e);
  50. }
  51. }
  52. void build(int l,int r,int now)
  53. {
  54. tree[now].l=l;
  55. tree[now].r=r;
  56. tree[now].val=0;
  57. if(l==r)
  58. {
  59. tree[now].val=val[_tid[l]];
  60. return ;
  61. }
  62. int mid=(l+r)>>1;
  63. build(l,mid,now<<1);
  64. build(mid+1,r,now<<1|1);
  65. }
  66. void down(int now)
  67. {
  68. tree[now<<1].val+=tree[now].val;
  69. tree[now<<1|1].val+=tree[now].val;
  70. tree[now].val=0;
  71. }
  72. void update(int l,int r,int now,int num)
  73. {
  74. if(l==tree[now].l && r==tree[now].r)
  75. {
  76. tree[now].val+=num;
  77. return ;
  78. }
  79. if(tree[now].val)
  80. down(now);
  81. int mid=(tree[now].l+tree[now].r)>>1;
  82. if(r<=mid)
  83. update(l,r,now<<1,num);
  84. else if(l>mid)
  85. update(l,r,now<<1|1,num);
  86. else
  87. {
  88. update(l,mid,now<<1,num);
  89. update(mid+1,r,now<<1|1,num);
  90. }
  91. }
  92. void change(int s,int e,int num)
  93. {
  94. while(top[s]!=top[e])
  95. {
  96. if(dep[top[s]]<dep[top[e]])
  97. swap(s,e);
  98. update(tid[top[s]],tid[s],1,num);
  99. s=fa[top[s]];
  100. }
  101. if(dep[s]>dep[e])
  102. swap(s,e);
  103. update(tid[s],tid[e],1,num);
  104. }
  105. int query(int l,int now)
  106. {
  107. if(tree[now].l==l && tree[now].r==l)
  108. return tree[now].val;
  109. if(tree[now].val)
  110. down(now);
  111. int mid=(tree[now].l+tree[now].r)>>1;
  112. if(l<=mid)
  113. return query(l,now<<1);
  114. else
  115. return query(l,now<<1|1);
  116. }
  117. int main()
  118. {
  119. while(cin>>n>>m>>q)
  120. {
  121. memset(size,0,sizeof(size));
  122. memset(fa,0,sizeof(fa));
  123. memset(tid,0,sizeof(tid));
  124. memset(son,0,sizeof(son));
  125. cnt=0;
  126. for(int i=1;i<=n;i++)
  127. {
  128. scanf("%d",&val[i]);
  129. map[i].clear();
  130. }
  131. for(int i=1;i<n;i++)
  132. {
  133. int a,b;
  134. scanf("%d%d",&a,&b);
  135. map[a].push_back(b);
  136. map[b].push_back(a);
  137. }
  138. dfs1(1,-1,1);
  139. dfs2(1,1);
  140. build(1,n,1);
  141. while(q--)
  142. {
  143. char ch[5];
  144. int a,b,c;
  145. scanf("%s",ch);
  146. if(ch[0]=='Q')
  147. {
  148. scanf("%d",&a);
  149. printf("%d\n",query(tid[a],1));
  150. }
  151. else
  152. {
  153. scanf("%d%d%d",&a,&b,&c);
  154. if(ch[0]=='I')
  155. change(a,b,c);
  156. else
  157. change(a,b,-c);
  158. }
  159. }
  160. }
  161. }

hdu3966_树链剖分的更多相关文章

  1. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

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

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

  3. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  4. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  5. 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)

    题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...

  6. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  7. bzoj2243树链剖分+染色段数

    终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...

  8. bzoj3631树链剖分

    虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...

  9. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

随机推荐

  1. EOJ 2847 路由结点

    数学知识 凸N边形的对角线条数为:n(n-3)/2因为每一个交点对应两条对角线,而两条对角线又对应着一个四边形.于是焦点个数就对应四边形的个数.问题转化成由凸n边形的n个顶点取4个顶点可组成多少个四边 ...

  2. 常见Java集合的实现细节

    1. Set和Map Set代表一种集合元素无序.集合元素不可重复的集合,Map则代表一种由多个key-value对组成的集合,Map集合类似于传统的关联数组.表面上看它们之间相似性很少,但实际上Ma ...

  3. canvas的自动画图

    <!DOCTYPE HTML><html><body> <canvas id="myCanvas" width="200&quo ...

  4. maven使用杂记

    maven test使用记录 运行指定的测试类:     >mvn test -Dtest=[ClassName] 运行测试类中指定的方法:(这个需要maven-surefire-plugin: ...

  5. CentOS6.5下nginx-1.8.1.tar.gz的单节点搭建(图文详解)

    不多说,直接上干货! [hadoop@djt002 local]$ su root Password: [root@djt002 local]# ll total drwxr-xr-x. root r ...

  6. VS2015启动显示无法访问此网站

    之前启动项目发生过几次,也忘了怎么解决了,今天记录一下:将应用文件夹下的vs目录删除,重新生成解决方案后,程序正常启动. 原文链接:https://blog.csdn.net/upi2u/articl ...

  7. hibernate dao 公共方法

    package com.dao.impl; import java.lang.reflect.ParameterizedType; import java.util.Collection; impor ...

  8. 【Oracle】创建角色

    任务:创建角色 1)创建角色sse_role,授予create session 权限 2)创建角色tblo_role,授予CREATE PROCEDURE, CREATE SEQUENCE, CREA ...

  9. 开源作品-PHP写的在线文件管理工具(单文件绿色版)-SuExplorer_PHP_3_0

    前言:项目开发过程中,网站一般部署到远程服务器,所以文件管理就不能和本机操作一样方便.通常文件管理是用ftp下载到本地,修改后再上传,或者远程登录到服务器进行修改.但是这些操作都依赖于复杂的第三方软件 ...

  10. zmodem使用方法

    无论有xshell还是secureCRT连接linux的时. 默认都用一个zmodem可以帮助window和linux之间传输文件 很方便和实用的工具. 不过默认是无法使用的 需要安装lrzsz软件 ...