Tree

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 920    Accepted Submission(s): 388

Problem Description
You are given a tree with N nodes which are numbered by integers 1..N. Each node is associated with an integer as the weight.

Your task is to deal with M operations of 4 types:

1.Delete an edge (x, y) from the tree, and then add a new edge (a, b). We ensure that it still constitutes a tree after adding the new edge.

2.Given two nodes a and b in the tree, change the weights of all the nodes on the path connecting node a and b (including node a and b) to a particular value x.

3.Given two nodes a and b in the tree, increase the weights of all the nodes on the path connecting node a and b (including node a and b) by a particular value d.

4.Given two nodes a and b in the tree, compute the second largest weight on the path connecting node a and b (including node a and b), and the number of times this weight occurs on the path. Note that here we need the strict second largest weight. For instance, the strict second largest weight of {3, 5, 2, 5, 3} is 3.

 
Input
The first line contains an integer T (T<=3), which means there are T test cases in the input.

For each test case, the first line contains two integers N and M (N, M<=10^5). The second line contains N integers, and the i-th integer is the weight of the i-th node in the tree (their absolute values are not larger than 10^4).

In next N-1 lines, there are two integers a and b (1<=a, b<=N), which means there exists an edge connecting node a and b.

The next M lines describe the operations you have to deal with. In each line the first integer is c (1<=c<=4), which indicates the type of operation.

If c = 1, there are four integers x, y, a, b (1<= x, y, a, b <=N) after c.
If c = 2, there are three integers a, b, x (1<= a, b<=N, |x|<=10^4) after c.
If c = 3, there are three integers a, b, d (1<= a, b<=N, |d|<=10^4) after c.
If c = 4 (it is a query operation), there are two integers a, b (1<= a, b<=N) after c.

All these parameters have the same meaning as described in problem description.

 
Output
For each test case, first output "Case #x:"" (x means case ID) in a separate line.

For each query operation, output two values: the second largest weight and the number of times it occurs. If the weights of nodes on that path are all the same, just output "ALL SAME" (without quotes).

 
Sample Input
2
3 2
1 1 2
1 2
1 3
4 1 2
4 2 3
7 7
5 3 2 1 7 3 6
1 2
1 3
3 4
3 5
4 6
4 7
4 2 6
3 4 5 -1
4 5 7
1 3 4 2 4
4 3 6
2 3 6 5
4 3 6
 
Sample Output
Case #1:
ALL SAME
1 2
Case #2:
3 2
1 1
3 2
ALL SAME
  1. /*
  2. hdu 5002 (动态树lct)
  3.  
  4. problem:
  5. 给你一棵树树,主要包含四个操作:
  6. 1 x y u v:断开x,y之间的边 连接上u,v
  7. 2 x y w:将x->y之间的点权全部置为w
  8. 3 x y w:将x->y之间的点权全部加上w
  9. 4 x y:查询x->y之间第二大的
  10.  
  11. solve:
  12. 只是需要维护下第二大值,其它直接套模板
  13.  
  14. hhh-2016-08-20 17:21:29
  15. */
  16. #pragma comment(linker,"/STACK:124000000,124000000")
  17. #include <algorithm>
  18. #include <iostream>
  19. #include <cstdlib>
  20. #include <cstdio>
  21. #include <cstring>
  22. #include <vector>
  23. #include <map>
  24. #define lson ch[0]
  25. #define rson ch[1]
  26. #define ll long long
  27. #define clr(a,b) memset(a,b,sizeof(a))
  28. #define key_val ch[ch[root][1]][0]
  29. using namespace std;
  30. const int maxn = 300100;
  31. const int INF = 0x3f3f3f3f;
  32.  
  33. struct Node* null;
  34. struct Node
  35. {
  36. Node* ch[2] ;
  37. Node* fa;
  38. int Size ;
  39. int mMax ;
  40. int sMax ;
  41. int max_num ;
  42. int Max_num ;
  43. int val ;
  44. int add ;
  45. int same ;
  46. int rev;
  47. void newnode(int v)
  48. {
  49. val = v ;
  50. mMax = v ;
  51. sMax = -INF ;
  52. Max_num = 1 ;
  53. max_num = 0 ;
  54. Size = 1 ;
  55. add = 0 ;
  56. same = -INF ;
  57. fa = ch[0] = ch[1] = null ;
  58. rev = 0;
  59. }
  60. void update_rev()
  61. {
  62. if(this == null)
  63. return ;
  64. swap(ch[0],ch[1]);
  65. rev ^= 1;
  66. }
  67. void update_add(int v)
  68. {
  69. if(this == null )return ;
  70. add += v;
  71. mMax += v,val += v;
  72. if(sMax != -INF) sMax += v;
  73. }
  74.  
  75. void update_same(int v)
  76. {
  77. if(this == null) return ;
  78. same = v;
  79. add = 0,val = v,mMax = v;
  80. sMax = -INF,Max_num = Size,max_num = 0;
  81. }
  82. void cal(int val,int num)
  83. {
  84. if ( val == -INF ) return ;
  85. if ( val < sMax ) return ;
  86. if ( val > mMax )
  87. {
  88. sMax = mMax ;
  89. max_num = Max_num ;
  90. mMax = val ;
  91. Max_num = num ;
  92. }
  93. else if ( val == mMax )
  94. {
  95. Max_num += num ;
  96. }
  97. else if ( val > sMax )
  98. {
  99. sMax = val ;
  100. max_num = num ;
  101. }
  102. else max_num += num ;
  103. }
  104. void push_up () {
  105. Size = ch[0]->Size + 1 + ch[1]->Size ;
  106. mMax = sMax = -INF ;
  107. max_num = Max_num = 0 ;
  108. cal ( val , 1 ) ;
  109. cal ( ch[0]->mMax , ch[0]->Max_num ) ;
  110. cal ( ch[0]->sMax , ch[0]->max_num ) ;
  111. cal ( ch[1]->mMax , ch[1]->Max_num ) ;
  112. cal ( ch[1]->sMax , ch[1]->max_num ) ;
  113. }
  114.  
  115. void push_down()
  116. {
  117. if(rev)
  118. {
  119. ch[0]->update_rev();
  120. ch[1]->update_rev();
  121. rev = 0;
  122. }
  123. if(same != -INF)
  124. {
  125. ch[0]->update_same(same);
  126. ch[1]->update_same(same);
  127. same = -INF;
  128. }
  129. if(add)
  130. {
  131. ch[0]->update_add(add);
  132. ch[1]->update_add(add);
  133. add = 0;
  134. }
  135. }
  136.  
  137. void link_child ( Node* to , int d )
  138. {
  139. ch[d] = to;
  140. to->fa = this ;
  141. }
  142.  
  143. int isroot()
  144. {
  145. return fa == null || this != fa->ch[0] && this != fa->ch[1] ;
  146. }
  147. void down()
  148. {
  149. if ( !isroot () ) fa->down () ;
  150. push_down () ;
  151. }
  152. void Rotate ( int d )
  153. {
  154. Node* f = fa ;
  155. Node* ff = fa->fa ;
  156. f->link_child ( ch[d] , !d ) ;
  157. if ( !f->isroot () )
  158. {
  159. if ( ff->ch[0] == f ) ff->link_child ( this , 0 ) ;
  160. else ff->link_child ( this , 1 ) ;
  161. }
  162. else fa = ff ;
  163. link_child (f,d) ;
  164. f->push_up () ;
  165. }
  166.  
  167. void splay ()
  168. {
  169. down () ;
  170. while ( !isroot () ) {
  171. if ( fa->isroot () ) {
  172. this == fa->ch[0] ? Rotate ( 1 ) : Rotate ( 0 ) ;
  173. } else {
  174. if ( fa == fa->fa->ch[0] ) {
  175. this == fa->ch[0] ? fa->Rotate ( 1 ) : Rotate ( 0 ) ;
  176. Rotate ( 1 ) ;
  177. } else {
  178. this == fa->ch[1] ? fa->Rotate ( 0 ) : Rotate ( 1 ) ;
  179. Rotate ( 0 ) ;
  180. }
  181. }
  182. }
  183. push_up () ;
  184. }
  185.  
  186. void access()
  187. {
  188. Node* now = this ;
  189. Node* x = null ;
  190. while ( now != null )
  191. {
  192. now->splay () ;
  193. now->link_child ( x , 1 ) ;
  194. now->push_up () ;
  195. x = now ;
  196. now = now->fa ;
  197. }
  198. splay () ;
  199. }
  200.  
  201. void make_root()
  202. {
  203. access();
  204. update_rev();
  205. }
  206.  
  207. void cut()
  208. {
  209. access();
  210. ch[0]->fa = null;
  211. ch[0] = null;
  212. push_up();
  213. }
  214. Node* find_root ()
  215. {
  216. access () ;
  217. Node* to = this ;
  218. while ( to->ch[0] != null )
  219. {
  220. to->push_down () ;
  221. to = to->ch[0] ;
  222. }
  223. return to ;
  224. }
  225. void cut(Node* to)
  226. {
  227. to->make_root();
  228. cut();
  229. }
  230.  
  231. void link(Node* to)
  232. {
  233. to->make_root();
  234. to->fa = this;
  235. }
  236. void make_same(Node* to,int val)
  237. {
  238. to->make_root();
  239. access();
  240. update_same(val);
  241. }
  242. void make_add(Node* to,int val)
  243. {
  244. to->make_root();
  245. access();
  246. update_add(val);
  247. }
  248. void query(Node* to)
  249. {
  250. to->make_root();
  251. access();
  252.  
  253. if(!max_num)
  254. printf("ALL SAME\n");
  255. else
  256. printf("%d %d\n",sMax,max_num);
  257. }
  258. };
  259. Node memory_pool[maxn];
  260. Node* now;
  261. Node* node[maxn];
  262.  
  263. void Clear()
  264. {
  265. now = memory_pool;
  266. now->newnode(-INF);
  267. null = now ++;
  268. null->Size = 0;
  269. }
  270.  
  271. int main()
  272. {
  273. int T,n,cas = 1,m;
  274. int x,y,a,b,c;
  275. int ob;
  276. // freopen("in.txt","r",stdin);
  277. scanf("%d",&T);
  278. while(T--)
  279. {
  280. Clear();
  281. scanf("%d%d",&n,&m);
  282. printf("Case #%d:\n",cas++);
  283. for(int i = 1; i <= n; i++)
  284. {
  285. scanf("%d",&x);
  286. now->newnode(x);
  287. node[i] = now++;
  288. }
  289.  
  290. for(int i = 1; i < n; i++)
  291. {
  292. scanf("%d%d",&a,&b);
  293. node[a]->link(node[b]);
  294.  
  295. }
  296. for(int i= 1; i <= m; i++)
  297. {
  298. scanf("%d",&ob);
  299. if(ob == 1)
  300. {
  301. scanf("%d%d%d%d",&x,&y,&a,&b);
  302. node[x]->cut(node[y]);
  303. node[a]->link(node[b]);
  304. }
  305. else if(ob == 2)
  306. {
  307. scanf("%d%d%d",&x,&y,&c);
  308. node[x]->make_same(node[y],c);
  309. }
  310. else if(ob == 3)
  311. {
  312. scanf("%d%d%d",&x,&y,&c);
  313. node[x]->make_add(node[y],c);
  314. }
  315. else if(ob == 4)
  316. {
  317. scanf("%d%d",&x,&y);
  318. node[x]->query(node[y]);
  319.  
  320. }
  321. }
  322. }
  323. return 0;
  324. }

  

hdu 5002 (动态树lct)的更多相关文章

  1. hdu 5398 动态树LCT

    GCD Tree Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  2. hdu 5314 动态树

    Happy King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  3. HDU 4718 The LCIS on the Tree (动态树LCT)

    The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Oth ...

  4. 动态树LCT小结

    最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...

  5. bzoj2049-洞穴勘测(动态树lct模板题)

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  6. [模板] 动态树/LCT

    简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...

  7. 动态树LCT(Link-cut-tree)总结+模板题+各种题目

    一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val:  令x点的点权变为val Query x y:  计算x,y之间的唯一的最短路径的点 ...

  8. SPOJ OTOCI 动态树 LCT

    SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...

  9. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2843  Solved: 1519[Submi ...

随机推荐

  1. 2017-2018-1 1623 bug终结者 冲刺007

    bug终结者 冲刺007 by 20162302 杨京典 今日任务:排行榜界面 排行榜界面,选项界面 简要说明 排行榜界面用于展示用户通关是所使用的步数和时间,选项界面可以调整背景音乐的开关.选择砖块 ...

  2. 在Apache中运行Python WSGI应用

    我们介绍如何使用Apache模块mod_wsgi来运行Python WSGI应用. 安装mod_wsgi 我们假设你已经有了Apache和Python环境,在Linux或者Mac上,那第一步自然是安装 ...

  3. logging日志

    import logging logging.basicConfig(filename='log.log', format='%(asctime)s - %(name)s - %(levelname) ...

  4. React 深入系列1:React 中的元素、组件、实例和节点

    文:徐超,<React进阶之路>作者 授权发布,转载请注明作者及出处 React 深入系列,深入讲解了React中的重点概念.特性和模式等,旨在帮助大家加深对React的理解,以及在项目中 ...

  5. Python脚本自动提取和替换代码中的中文

    # -*- coding: utf-8 -*- import os import os.path import re import sys reload(sys) sys.setdefaultenco ...

  6. 我自己总结的C#开发命名规范整理了一份

    我自己总结的C#开发命名规范整理了一份 标签: 开发规范文档标准语言 2014-06-27 22:58 3165人阅读 评论(1) 收藏 举报  分类: C#(39)  版权声明:本文为博主原创文章, ...

  7. kafka安装使用和遇到的坑

    下载安装 参考:https://segmentfault.com/a/1190000012730949 ​ https://kafka.apache.org/quickstart 关闭服务 关闭zoo ...

  8. SpringBoot应用的前台目录

    一.两个重要目录 templates:存放web页面的模板文件,需要在controller返回视图名称,框架转发才能找到的html. static :存放静态资源,如:html(放在这里可直接访问,如 ...

  9. Angular 学习笔记 ( 链接服务器 )

    ng 是做前端开发的, 所以通常我们会配上一个 API server. 本地调试时通常使用 proxy https://github.com/angular/angular-cli/blob/mast ...

  10. JS解析JSON字符串

    问题描述:后台需要传递给前台一些数据,用于页面数据显示,因为是一些Lable标签,所以数据传递到前台需要解析. 思路:因为数据比较杂乱,所以我选择传递的数据类型是Json格式,但是数据展示时需要解析成 ...