5210: 最大连通子块和

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 211  Solved: 65
[Submit][Status][Discuss]

Description

给出一棵n个点、以1为根的有根树,点有点权。要求支持如下两种操作:
M x y:将点x的点权改为y;
Q x:求以x为根的子树的最大连通子块和。
其中,一棵子树的最大连通子块和指的是:该子树所有子连通块的点权和中的最大值
(本题中子连通块包括空连通块,点权和为0)。

Input

第一行两个整数n、m,表示树的点数以及操作的数目。
第二行n个整数,第i个整数w_i表示第i个点的点权。
接下来的n-1行,每行两个整数x、y,表示x和y之间有一条边相连。
接下来的m行,每行输入一个操作,含义如题目所述。保证操作为M x y或Q x之一。
1≤n,m≤200000 ,任意时刻 |w_i|≤10^9 。

Output

对于每个Q操作输出一行一个整数,表示询问子树的最大连通子块和。

Sample Input

5 4
3 -2 0 3 -1
1 2
1 3
4 2
2 5
Q 1
M 4 1
Q 1
Q 2

Sample Output

4
3
1

我不知道什么动态dp,我只知道这是一个数据结构题。每次写个树链刨分都得弄半天orz。
大神题解:CQzhangyu
 
  1. #include<bits/stdc++.h>
  2. #define clr(x) memset(x,0,sizeof(x))
  3. #define clr_1(x) memset(x,-1,sizeof(x))
  4. #define INF 0x3f3f3f3f
  5. #define LL long long
  6. #define pb push_back
  7. #define ls(i) (i<<1)
  8. #define rs(i) (i<<1|1)
  9. #define mp make_pair
  10. #define fi first
  11. #define se second
  12. using namespace std;
  13. const int N=2e5+;
  14. int tsize[N];
  15. int son[N],down[N],top[N],dep[N],pos[N],pot[N],fat[N];
  16. int tot;
  17. int n,q;
  18. LL v[N],f[N],g[N],maxs[N];
  19. vector<int> e[N];
  20. struct heap
  21. {
  22. priority_queue<LL> ins,del;
  23. inline void push(LL x)
  24. {
  25. ins.push(x);
  26. return ;
  27. }
  28. inline void pop(LL x)
  29. {
  30. del.push(x);
  31. return ;
  32. }
  33. inline LL top()
  34. {
  35. while(!del.empty() && ins.top()==del.top())
  36. ins.pop(),del.pop();
  37. if(ins.empty()) return 0LL;
  38. return ins.top();
  39. }
  40. void pop()
  41. {
  42. top();
  43. del.push(ins.top());
  44. return ;
  45. }
  46. }lsq[N];
  47. void dfs1(int u,int d,int fa)
  48. {
  49. // cout<<"begin:"<<u<<" "<<son[u]<<endl;
  50. dep[u]=d;
  51. tsize[u]=;
  52. fat[u]=fa;
  53. int sz=e[u].size(),p;
  54. for(int i=;i<sz;i++)
  55. {
  56. p=e[u][i];
  57. // cout<<"branch:"<<u<<" "<<p<<" "<<fa<<endl;
  58. if(p!=fa)
  59. {
  60. dfs1(p,d+,u);
  61. tsize[u]+=tsize[p];
  62. if(!son[u] || tsize[p]>tsize[son[u]])
  63. son[u]=p;
  64. }
  65. }
  66. // cout<<"endn:"<<u<<" "<<son[u]<<endl;
  67. return ;
  68. }
  69. void dfs2(int u,int tp)
  70. {
  71. // cout<<u<<endl;
  72. top[u]=tp;
  73. pos[u]=++tot;
  74. pot[tot]=u;
  75. if(son[u]) dfs2(son[u],tp),down[u]=down[son[u]],maxs[u]=maxs[son[u]];
  76. else down[u]=u,maxs[u]=;
  77. int sz=e[u].size();
  78. g[u]=v[u];
  79. for(int i=;i<sz;i++)
  80. {
  81. int p=e[u][i];
  82. if(p!=fat[u] && p!=son[u])
  83. {
  84. dfs2(p,p);
  85. g[u]+=f[p];
  86. lsq[u].push(maxs[p]);
  87. }
  88. }
  89. f[u]=max(0LL,g[u]+f[son[u]]),maxs[u]=max(maxs[u],f[u]),maxs[u]=max(maxs[u],lsq[u].top());
  90. return ;
  91. }
  92. struct segt
  93. {
  94. int l,r;
  95. LL all,maxl,maxr,maxn;
  96. segt operator + (const segt &b)
  97. {
  98. segt p;
  99. p.maxl=max(maxl,all+b.maxl);
  100. p.maxr=max(b.maxr,maxr+b.all);
  101. p.all=all+b.all;
  102. p.maxn=max(max(maxn,b.maxn),maxr+b.maxl);
  103. p.l=l;
  104. p.r=b.r;
  105. return p;
  106. }
  107. }seg[N<<];
  108. void init(int i,int l,int r)
  109. {
  110. if(l==r)
  111. {
  112. int x=pot[l];
  113. seg[i]=(segt){l,r,g[x],max(0LL,g[x]),max(0LL,g[x]),max(g[x],lsq[x].top())};
  114. return ;
  115. }
  116. int mid=l+r>>;
  117. init(i<<,l,mid);
  118. init(i<<|,mid+,r);
  119. seg[i]=seg[i<<]+seg[i<<|];
  120. return ;
  121. }
  122. char s[];
  123. void refresh(int i,int pos)
  124. {
  125. if(seg[i].l==seg[i].r)
  126. {
  127. int x=pot[seg[i].l];
  128. segt p=(segt){seg[i].l,seg[i].r,g[x],max(0LL,g[x]),max(0LL,g[x]),max(g[x],lsq[x].top())};
  129. seg[i]=p;
  130. return ;
  131. }
  132. int mid=seg[i].l+seg[i].r>>;
  133. if(mid>=pos) refresh(i<<,pos);
  134. else refresh(i<<|,pos);
  135.  
  136. seg[i]=seg[i<<]+seg[i<<|];
  137. return ;
  138. }
  139. segt query(int i,int l,int r)
  140. {
  141. if(seg[i].l>=l && seg[i].r<=r) return seg[i];
  142. int mid=seg[i].l+seg[i].r>>;
  143. if(r<=mid) return query(i<<,l,r);
  144. if(l>mid) return query(i<<|,l,r);
  145. return query(i<<,l,r)+query(i<<|,l,r);
  146. }
  147. void update(int u,LL val)
  148. {
  149. segt t1,t2,t3;
  150. bool flag=;
  151. // cout<<u<<endl;
  152. while(u)
  153. {
  154. // cout<<u<<endl;
  155. t3=query(,pos[top[u]],pos[down[u]]);
  156. if(flag) lsq[u].pop(t1.maxn),lsq[u].push(t2.maxn);
  157. t1=t3;
  158. flag=;
  159. g[u]+=val,refresh(,pos[u]);
  160. t2=query(,pos[top[u]],pos[down[u]]);
  161. val=t2.maxl-f[top[u]],f[top[u]]=t2.maxl;
  162. u=fat[top[u]];
  163. }
  164. return ;
  165. }
  166. int main()
  167. {
  168. tot=;
  169. scanf("%d%d",&n,&q);
  170. for(int i=;i<=n;i++)
  171. scanf("%lld",v+i);
  172. for(int i=;i<=n;i++)
  173. {
  174. int u,v;
  175. scanf("%d%d",&u,&v);
  176. e[u].pb(v);
  177. e[v].pb(u);
  178. }
  179. dfs1(,,);
  180. dfs2(,);
  181. init(,,n);
  182. for(int i=;i<=q;i++)
  183. {
  184. scanf("%s",s);
  185. if(s[]=='M')
  186. {
  187. int u;
  188. LL num;
  189. scanf("%d%lld",&u,&num);
  190. update(u,num-v[u]);
  191. v[u]=num;
  192. }
  193. else
  194. {
  195. int u;
  196. scanf("%d",&u);
  197. printf("%lld\n",query(,pos[u],pos[down[u]]).maxn);
  198. }
  199. }
  200. return ;
  201. }

bzoj 5210(树链刨分下做个dp)的更多相关文章

  1. hdu 5452(树链刨分)

    看到题目,想了挺长时间,发现不会,然后看着样子像是树上成段操作,所以查了下树链刨分,结果真的就是这个东西... Minimum Cut Time Limit: 3000/2000 MS (Java/O ...

  2. xcoj 1103 插线板(树链刨分求最大子段和)

    1103: 插线板 时间限制: 1 Sec  内存限制: 128 MB提交: 14  解决: 7 标签提交统计讨论版EditTestData 题目描述 从前有一堆古老的插线板,任意两个插线板之间只有一 ...

  3. 树链刨分(class版)

    class版树链剖(刨)分 感谢沙华大佬的赞助 其实没什么太大变化,就是用了几次一顿乱指... CODE: #include<iostream> #include<cstdio> ...

  4. HDU - 3966 树链刨分

    题目传送门 操作就是询问某个点的值, 然后就是对一条路径上的值全部修改. 最基本的树刨题目了. 树刨的思想: 1. 对于每个点找到他的重儿子. void dfs1(int o, int u){ sz[ ...

  5. P3565 由简单的树形dp 引入 长链刨分

    这道题感觉不太行 因为自己没想出来. 先说一下暴力吧,取三个点 让两两之间的距离相等怎么做呢,看起来是很复杂的样子的,但是仔细观察发现 答案出自一个点的儿子之间 或者儿子和父亲之间. 暴力枚举三个点然 ...

  6. POJ 2763 Housewife Wind 树链拋分

    一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主 ...

  7. HDU 3966 Aragorn's Story 树链拋分

    一.写在前面 终于开始开坑link-cut-tree这个了,对于网上找到的大佬的前进路线,进行了一番研发,发现实际上可以实现对于树链拋分的制作.经历了若干长时间之后终于打了出来(为什么每次学什么东西都 ...

  8. BZOJ 1036 && 树链剖分

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

  9. bzoj 4196 树链剖分 模板

    [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2135  Solved: 1232[Submit][Status][D ...

随机推荐

  1. mogodb的安装与配置

    下载:https://www.mongodb.com/https://www.mongodb.com/ 安装:一直next,中间选择custom,选择自己的安装路径,最后安装成功. 配置:打开安装好的 ...

  2. flask基础之AppContext应用上下文和RequestContext请求上下文(六)

    前言 应用上下文和请求上下文存在的目的,官方文档讲的很清楚,可参考: http://www.pythondoc.com/flask/appcontext.html 应用上下文对象在没有请求的时候是可以 ...

  3. httpd功能配置之虚拟主机【转】

    apache默认使用80端口提供服务,使用主服务器配置的话,一台物理机只能提供一个站点服务:可以使用虚拟主机方式提供不同的访问,以实现一台主机提供多站点服务. 虚拟主机的实现方式有三种:基于端口.基于 ...

  4. 企业日志大数据分析系统ELK+KAFKA实现【转】

    背景: 最近线上上了ELK,但是只用了一台Redis在中间作为消息队列,以减轻前端es集群的压力,Redis的集群解决方案暂时没有接触过,并且Redis作为消息队列并不是它的强项:所以最近将Redis ...

  5. Runtime.getRuntime().exec 类 防止阻塞

    import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; impor ...

  6. idea心得

    概述 Intellij IDEA真是越用越觉得它强大,它总是在我们写代码的时候,不时给我们来个小惊喜.出于对Intellij IDEA的喜爱,我决定写一个与其相关的专栏或者系列,把一些好用的Intel ...

  7. pip离线安装

    pip freeze > requirements.txt pip download <packages> pip install --no-index --find-links=& ...

  8. 用js面向对象思想封装插件

    js是基于原型的面向对象语言,如果你学过java,c#等正统面向对象语言,你会难以理解js的面向对象,他和普通的面向对象不太一样,今天,我们通过封装一个toast插件,来看看js面向对象是如何运行的. ...

  9. YUI Compressor 压缩 JavaScript 原理-《转载》

    YUI Compressor 压缩 JavaScript 的内容包括: 移除注释 移除额外的空格 细微优化 标识符替换(Identifier Replacement) YUI Compressor包括 ...

  10. Oracle学习笔记:ORA-22992 cannot use LOB locators selected from remote tables

    通过DB_LINK访问远程表的时候出现 ORA-22992: cannot use LOB locators selected from remote tables 错误. 原因:因为表中含有clob ...