题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/E

题意:给定一棵树及树上的点权,要求三种操作:

1)CHANGE u t : 把结点u的权值改为t。

2)QMAX u v: 询问从点u到点v的路径上的节点的最大权值。

3)QSUM u v: 询问从点u到点v的路径上的节点的权值和

分析:树链剖分后就是线段树的单点修改,区间求和与区间求最值。。。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <string>
  4. #include <cmath>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <cstdlib>
  9. #include <stack>
  10. #include <vector>
  11. #include <set>
  12. #include <map>
  13. #define LL long long
  14. #define mod 10007
  15. #define inf 0x3f3f3f3f
  16. #define N 100010
  17. #define FILL(a,b) (memset(a,b,sizeof(a)))
  18. #define lson l,m,rt<<1
  19. #define rson m+1,r,rt<<1|1
  20. using namespace std;
  21. struct edge
  22. {
  23. int to,next;
  24. edge(){}
  25. edge(int to,int next):to(to),next(next){}
  26. }e[N<<];
  27. int head[N<<],tot;
  28. int top[N];//top[v]表示v所在的重链的顶端节点
  29. int fa[N];//父亲节点
  30. int dep[N];//深度
  31. int sz[N];//si[v]表示以v为根节点的子树的节点数
  32. int son[N];//重儿子
  33. int p[N];//p[v]表示v与其父亲节点的连边在线段树中的位置
  34. int fp[N];//与p数组相反
  35. int pos;//所有链构成的线段树总长度
  36. int sum[N<<],mx[N<<],a[N];
  37. void addedge(int u,int v)
  38. {
  39. e[tot]=edge(v,head[u]);
  40. head[u]=tot++;
  41. }
  42. void init()
  43. {
  44. tot=;FILL(head,-);
  45. pos=;FILL(son,-);
  46. }
  47. void dfs(int u,int f,int d)
  48. {
  49. dep[u]=d;sz[u]=;fa[u]=f;
  50. for(int i=head[u];~i;i=e[i].next)
  51. {
  52. int v=e[i].to;
  53. if(v==f)continue;
  54. dfs(v,u,d+);
  55. sz[u]+=sz[v];
  56. if(son[u]==-||sz[son[u]]<sz[v])son[u]=v;
  57. }
  58. }
  59. void getpos(int u,int sp)
  60. {
  61. top[u]=sp;
  62. p[u]=++pos;
  63. fp[pos]=u;
  64. if(son[u]==-)return;
  65. getpos(son[u],sp);
  66. for(int i=head[u];~i;i=e[i].next)
  67. {
  68. int v=e[i].to;
  69. if(v!=son[u]&&v!=fa[u])
  70. {
  71. getpos(v,v);
  72. }
  73. }
  74. }
  75. void Pushup(int rt)
  76. {
  77. int ls=rt<<,rs=ls|;
  78. sum[rt]=sum[ls]+sum[rs];
  79. mx[rt]=max(mx[ls],mx[rs]);
  80. }
  81. void build(int l,int r,int rt)
  82. {
  83. if(l==r)
  84. {
  85. mx[rt]=sum[rt]=a[fp[l]];
  86. return;
  87. }
  88. int m=(l+r)>>;
  89. build(lson);
  90. build(rson);
  91. Pushup(rt);
  92. }
  93. void update(int ps,int c,int l,int r,int rt)
  94. {
  95. if(l==r)
  96. {
  97. mx[rt]=sum[rt]=c;
  98. return;
  99. }
  100. int m=(l+r)>>;
  101. if(ps<=m)update(ps,c,lson);
  102. else update(ps,c,rson);
  103. Pushup(rt);
  104. }
  105. int querysum(int L,int R,int l,int r,int rt)
  106. {
  107. if(L<=l&&r<=R)
  108. return sum[rt];
  109. int m=(l+r)>>;
  110. int res=;
  111. if(L<=m)res+=querysum(L,R,lson);
  112. if(R>m)res+=querysum(L,R,rson);
  113. return res;
  114. }
  115. int querymax(int L,int R,int l,int r,int rt)
  116. {
  117. if(L<=l&&r<=R)
  118. return mx[rt];
  119. int m=(l+r)>>;
  120. int res=-inf;
  121. if(L<=m)res=max(res,querymax(L,R,lson));
  122. if(m<R)res=max(res,querymax(L,R,rson));
  123. return res;
  124. }
  125. int lca(int u,int v,int flag)
  126. {
  127. int fu=top[u],fv=top[v],res;
  128. if(flag)res=-inf;
  129. else res=;
  130. while(fu!=fv)
  131. {
  132. if(dep[fu]<dep[fv])
  133. {
  134. swap(fu,fv);
  135. swap(u,v);
  136. }
  137. if(flag)res=max(res,querymax(p[fu],p[u],,pos,));
  138. else res+=querysum(p[fu],p[u],,pos,);
  139. u=fa[fu];fu=top[u];
  140. }
  141. if(dep[u]>dep[v])swap(u,v);
  142. if(flag)res=max(res,querymax(p[u],p[v],,pos,));
  143. else res+=querysum(p[u],p[v],,pos,);
  144. return res;
  145. }
  146. int main()
  147. {
  148. int n,t,u,v,w;
  149. char op[];
  150. while(scanf("%d",&n)>)
  151. {
  152. init();
  153. for(int i=;i<n;i++)
  154. {
  155. scanf("%d%d",&u,&v);
  156. addedge(u,v);
  157. addedge(v,u);
  158. }
  159. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  160. dfs(,,);
  161. getpos(,);
  162. build(,pos,);
  163. scanf("%d",&t);
  164. while(t--)
  165. {
  166. scanf("%s",op);
  167. scanf("%d%d",&u,&v);
  168. if(op[]=='S')
  169. {
  170. printf("%d\n",lca(u,v,));
  171. }
  172. else if(op[]=='M')
  173. {
  174. printf("%d\n",lca(u,v,));
  175. }
  176. else
  177. {
  178. update(p[u],v,,pos,);
  179. }
  180. }
  181. }
  182. }

HYSBZ 1036(树链剖分)的更多相关文章

  1. HYSBZ 1036树链剖分

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从 ...

  2. HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分

    树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...

  3. BZOJ 1036 && 树链剖分

    还是太弱啊..各种数据结构只听过名字却没有一点概念..树链剖分也在这个范畴..今天来进一步深化一下教育改革推进全民素质提高. 性质 忘了在哪里看到的一篇blog有一句话讲得非常好,树链剖分不是一种数据 ...

  4. HYSBZ - 2243 树链剖分 + 线段树 处理树上颜色段数

    用线段树处理颜色段数 记录区间内的颜色段数,区间右端点的颜色,区间右端点的颜色. int tr[maxn<<2], lc[maxn<<2], rc[maxn<<2] ...

  5. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...

  6. Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)

    Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...

  7. HYSBZ 1036 【树链剖分】

    思路: 裸裸的树链剖分.... 树链剖分就是把一棵树分成若干重链和轻链...然后保证形成的线段树上每条链是连续存储的.然后这样就能用线段树进行维护了. 但是每次一定要保证是在同一条链里边....思路就 ...

  8. HYSBZ 1036 树的统计Count(树链剖分)题解

    思路: 树链剖分,不知道说什么...我连模板都不会用 代码: #include<map> #include<ctime> #include<cmath> #incl ...

  9. BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14302  Solved: 5779[Submit ...

随机推荐

  1. Web前端,高性能优化

    高性能HTML 一.避免使用iframe iframe也叫内联frame,可将一个HTML文档嵌入另一个HTML文档中. iframe的好处是,嵌入的文档独立于父文档,通常也借此使浏览器模拟多线程.缺 ...

  2. 从注册流程 分析如何安全退出多个Activity 多种方式(附DEMO)

    前言   由于一个同学问到我如何按照一个流程走好之后回到首页,我以前看到过4个解决方案,后来发现有做个记录和总结的必要,就写了这篇博文.(之前看小强也写过一篇,这里通过自身的分析完整的总结一下以下6种 ...

  3. JSP的学习(3)——语法知识二之page指令

    本篇接上一篇<JSP的学习(2)——语法知识一>,继续来学习JSP的语法.本文主要从JSP指令中的page指令,对其各个属性进行详细的学习: JSP指令: JSP指令是为JSP引擎而设计的 ...

  4. HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)

    磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add  把d加到第k个数上去2 ...

  5. hdu 4710 Balls Rearrangement 数论

    这个公倍数以后是循环的很容易找出来,然后循环以内的计算是打表找的规律,规律比较难表述,自己看代码吧.. #include <iostream> #include <cstdio> ...

  6. perl 使用cookie

    use Net::SMTP; use LWP::UserAgent; use HTTP::Cookies; use HTTP::Headers; use HTTP::Response; use Enc ...

  7. linux c正则

    c 正则 --------------------------------------------------    标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一 ...

  8. 【设计模式】Singleton模式C++实现

    Singleton是设计模式中比较简单的一个.园中的朋友们应该都很熟悉了.前段时间参加xxx外企的面试,和面试官讨论C++的时候正好写了一个.当时由于在有些地方考虑不太周全,代码出现了一些疏漏.不过最 ...

  9. 14.4.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预读

    14.4.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预读 一个预读请求 是一个I ...

  10. html浏览器兼容性的 JavaScript语法

    1.      在FireFox中能够使用与HTML节点对象ID属性值同样的JS变量名称.可是IE中不行. 解决的方法:在命名上区分HTML节点对象ID属性值和JS变量 2.      IE不支持JS ...