The LCIS on the Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 175    Accepted Submission(s): 40

Problem Description
For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i <= j <= N and Si < Si+1 < Si+2 < ... < Sj-1 < Sj , then the sequence Si, Si+1, ... , Sj is a CIS(Continuous Increasing Subsequence). The longest CIS of a sequence is called the LCIS (Longest Continuous Increasing Subsequence).
Now we consider a tree rooted at node 1. Nodes have values. We have Q queries, each with two nodes u and v. You have to find the shortest path from u to v. And write down each nodes' value on the path, from u to v, inclusive. Then you will get a sequence, and please show us the length of its LCIS.
 
Input
The first line has a number T (T <= 10) , indicating the number of test cases.
For each test case, the first line is a number N (N <= 105), the number of nodes in the tree.
The second line comes with N numbers v1, v2, v3 ... , vN, describing the value of node 1 to node N. (1 <= vi <= 109)
The third line comes with N - 1 numbers p2, p3, p4 ... , pN, describing the father nodes of node 2 to node N. Node 1 is the root and will have no father.
Then comes a number Q, it is the number of queries. (Q <= 105)
For next Q lines, each with two numbers u and v. As described above.
 
Output
For test case X, output "Case #X:" at the first line.
Then output Q lines, each with an answer to the query.
There should be a blank line *BETWEEN* each test case.
 
Sample Input
1
5
1 2 3 4 5
1 1 3 3
3
1 5
4 5
2 5
 
Sample Output
Case #1:
3
2
3
 
Source
 
Recommend
zhuyuanchen520
 

用动态树把这题A掉了,

感觉很爽,一写就A了。

只有用动态树,splay维护最长连续上升子序列,注意更新操作

  1. /* ***********************************************
  2. Author :kuangbin
  3. Created Time :2013-9-13 21:03:22
  4. File Name :HDU4718.cpp
  5. ************************************************ */
  6.  
  7. #pragma comment(linker, "/STACK:1024000000,1024000000")
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <iostream>
  11. #include <algorithm>
  12. #include <vector>
  13. #include <queue>
  14. #include <set>
  15. #include <map>
  16. #include <string>
  17. #include <math.h>
  18. #include <stdlib.h>
  19. #include <time.h>
  20. using namespace std;
  21. #define REP(I, N) for (int I=0;I<int(N);++I)
  22. #define FOR(I, A, B) for (int I=int(A);I<int(B);++I)
  23. #define DWN(I, B, A) for (int I=int(B-1);I>=int(A);--I)
  24. #define REP_1(I, N) for (int I=1;I<=int(N);++I)
  25. #define FOR_1(I, A, B) for (int I=int(A);I<=int(B);++I)
  26. #define DWN_1(I, B, A) for (int I=int(B);I>=int(A);--I)
  27. #define REP_C(I, N) for (int N____=int(N),I=0;I<N____;++I)
  28. #define FOR_C(I, A, B) for (int B____=int(B),I=A;I<B____;++I)
  29. #define DWN_C(I, B, A) for (int A____=int(A),I=B-1;I>=A____;--I)
  30. #define REP_1_C(I, N) for (int N____=int(N),I=1;I<=N____;++I)
  31. #define FOR_1_C(I, A, B) for (int B____=int(B),I=A;I<=B____;++I)
  32. #define DWN_1_C(I, B, A) for (int A____=int(A),I=B;I>=A____;--I)
  33. #define DO(N) while(N--)
  34. #define DO_C(N) int N____ = N; while(N____--)
  35. #define TO(i, a, b) int s_=a<b?1:-1,b_=b+s_;for(int i=a;i!=b_;i+=s_)
  36. #define TO_1(i, a, b) int s_=a<b?1:-1,b_=b;for(int i=a;i!=b_;i+=s_)
  37. #define SQZ(I, J, A, B) for (int I=int(A),J=int(B)-1;I<J;++I,--J)
  38. #define SQZ_1(I, J, A, B) for (int I=int(A),J=int(B);I<=J;++I,--J)
  39.  
  40. const int MAXN = ;
  41. int ch[MAXN][], pre[MAXN], key[MAXN];
  42. int rev[MAXN];
  43. int size[MAXN];
  44. int la[MAXN], ra[MAXN], ma[MAXN];//递增的长度
  45. int ls[MAXN], rs[MAXN], ms[MAXN];//递减的长度
  46. int lv[MAXN], rv[MAXN];
  47. bool rt[MAXN];
  48.  
  49. void Update_Rev(int r)
  50. {
  51. if(!r)return;
  52. swap(ch[r][],ch[r][]);
  53. swap(lv[r],rv[r]);
  54. swap(la[r],rs[r]);
  55. swap(ls[r],ra[r]);
  56. swap(ma[r],ms[r]);
  57. rev[r] ^= ;
  58. }
  59. void push_down(int r)
  60. {
  61. if(rev[r])
  62. {
  63. Update_Rev(ch[r][]);
  64. Update_Rev(ch[r][]);
  65. rev[r] = ;
  66. }
  67. }
  68. void push_up(int r)
  69. {
  70. size[r] = size[ch[r][]] + size[ch[r][]] + ;
  71. if(ch[r][])lv[r] = lv[ch[r][]];
  72. else lv[r] = key[r];
  73. if(ch[r][])rv[r] = rv[ch[r][]];
  74. else rv[r] = key[r];
  75.  
  76. if(ch[r][] == )
  77. {
  78. if(ch[r][] == )
  79. {
  80. la[r] = ;
  81. ls[r] = ;
  82. }
  83. else
  84. {
  85. if(key[r] < lv[ch[r][]])
  86. la[r] = +la[ch[r][]];
  87. else la[r] = ;
  88. if(key[r] > lv[ch[r][]])
  89. ls[r] = + ls[ch[r][]];
  90. else ls[r] = ;
  91. }
  92. }
  93. else
  94. {
  95. if(la[ch[r][]] == size[ch[r][]])
  96. {
  97. if(rv[ch[r][]] < key[r])
  98. {
  99. if(ch[r][] == )
  100. la[r] = la[ch[r][]] + ;
  101. else
  102. {
  103. if(key[r] < lv[ch[r][]])
  104. la[r] = la[ch[r][]] + + la[ch[r][]];
  105. else la[r] = la[ch[r][]] + ;
  106. }
  107. }
  108. else la[r] = la[ch[r][]];
  109. }
  110. else la[r] = la[ch[r][]];
  111.  
  112. if(ls[ch[r][]] == size[ch[r][]])
  113. {
  114. if(rv[ch[r][]] > key[r])
  115. {
  116. if(ch[r][] == )
  117. ls[r] = ls[ch[r][]] + ;
  118. else
  119. {
  120. if(key[r] > lv[ch[r][]])
  121. ls[r] = ls[ch[r][]] + + ls[ch[r][]];
  122. else ls[r] = ls[ch[r][]] + ;
  123. }
  124. }
  125. else ls[r] = ls[ch[r][]];
  126. }
  127. else ls[r] = ls[ch[r][]];
  128.  
  129. }
  130.  
  131. if(ch[r][] == )
  132. {
  133. if(ch[r][] == )
  134. {
  135. ra[r] = ;
  136. rs[r] = ;
  137. }
  138. else
  139. {
  140. if(key[r] > rv[ch[r][]])
  141. ra[r] = ra[ch[r][]] + ;
  142. else ra[r] = ;
  143. if(key[r] < rv[ch[r][]])
  144. rs[r] = rs[ch[r][]] + ;
  145. else rs[r] = ;
  146. }
  147. }
  148. else
  149. {
  150. if(ra[ch[r][]] == size[ch[r][]])
  151. {
  152. if(key[r] < lv[ch[r][]])
  153. {
  154. if(ch[r][] == )
  155. ra[r] = ra[ch[r][]] + ;
  156. else
  157. {
  158. if(key[r] > rv[ch[r][]])
  159. ra[r] = ra[ch[r][]] + + ra[ch[r][]];
  160. else ra[r] = ra[ch[r][]] + ;
  161. }
  162. }
  163. else ra[r] = ra[ch[r][]];
  164. }
  165. else ra[r] = ra[ch[r][]];
  166.  
  167. if(rs[ch[r][]] == size[ch[r][]])
  168. {
  169. if(key[r] > lv[ch[r][]])
  170. {
  171. if(ch[r][] == )
  172. rs[r] = rs[ch[r][]] + ;
  173. else
  174. {
  175. if(key[r] < rv[ch[r][]])
  176. rs[r] = rs[ch[r][]] + + rs[ch[r][]];
  177. else rs[r] = rs[ch[r][]] + ;
  178. }
  179. }
  180. else rs[r] = rs[ch[r][]];
  181. }
  182. else rs[r] = rs[ch[r][]];
  183.  
  184. }
  185.  
  186. ma[r] = max(ma[ch[r][]],ma[ch[r][]]);
  187. ms[r] = max(ms[ch[r][]],ms[ch[r][]]);
  188. int tmp = ;
  189. if(ch[r][] && key[r] > rv[ch[r][]])
  190. tmp += ra[ch[r][]];
  191. if(ch[r][] && key[r] < lv[ch[r][]])
  192. tmp += la[ch[r][]];
  193. ma[r] = max(ma[r],tmp);
  194. tmp= ;
  195. if(ch[r][] && key[r] < rv[ch[r][]])
  196. tmp += rs[ch[r][]];
  197. if(ch[r][] && key[r] > lv[ch[r][]])
  198. tmp += ls[ch[r][]];
  199. ms[r] = max(ms[r],tmp);
  200.  
  201. }
  202. void Rotate(int x)
  203. {
  204. int y = pre[x], kind = ch[y][]==x;
  205. ch[y][kind] = ch[x][!kind];
  206. pre[ch[y][kind]] = y;
  207. pre[x] = pre[y];
  208. pre[y] = x;
  209. ch[x][!kind] = y;
  210. if(rt[y])
  211. rt[y] = false, rt[x] = true;
  212. else
  213. ch[pre[x]][ch[pre[x]][]==y] = x;
  214. push_up(y);
  215. }
  216. void P(int r)
  217. {
  218. if(!rt[r])P(pre[r]);
  219. push_down(r);
  220. }
  221. void Splay(int r)
  222. {
  223. P(r);
  224. while( !rt[r] )
  225. {
  226. int f = pre[r], ff = pre[f];
  227. if(rt[f])
  228. Rotate(r);
  229. else if( (ch[ff][]==f) == (ch[f][]==r) )
  230. Rotate(f), Rotate(r);
  231. else
  232. Rotate(r), Rotate(r);
  233. }
  234. push_up(r);
  235. }
  236. int Access(int x)
  237. {
  238. int y = ;
  239. for( ; x ; x = pre[y=x])
  240. {
  241. Splay(x);
  242. rt[ch[x][]] = true, rt[ch[x][]=y] = false;
  243. push_up(x);
  244. }
  245. return y;
  246. }
  247. int mroot(int r)
  248. {
  249. Access(r);
  250. Splay(r);
  251. Update_Rev(r);
  252. }
  253.  
  254. int main()
  255. {
  256. //freopen("in.txt","r",stdin);
  257. //freopen("out.txt","w",stdout);
  258. int T;
  259. int n;
  260. int Q;
  261. int u,v;
  262. scanf("%d",&T);
  263. int iCase = ;
  264. while(T--)
  265. {
  266. iCase++;
  267. scanf("%d",&n);
  268. for(int i = ;i <= n;i++)
  269. {
  270. pre[i] = ;
  271. ch[i][] = ch[i][] = ;
  272. rev[i] = ;
  273. rt[i] = true;
  274. la[i] = ra[i] = ma[i] = ;
  275. ls[i] = rs[i] = ms[i] = ;
  276. size[i] = ;
  277. }
  278. pre[] = ;
  279. ch[][] = ch[][] = ;
  280. rev[] = ;
  281. rt[] = true;
  282. la[] = ra[] = ma[] = ;
  283. ls[] = rs[] = ms[] = ;
  284. size[] = ;
  285.  
  286. for(int i = ;i <= n;i++)
  287. {
  288. scanf("%d",&key[i]);
  289. lv[i] = rv[i] = key[i];
  290. }
  291. for(int i = ;i <= n;i++)
  292. scanf("%d",&pre[i]);
  293.  
  294. printf("Case #%d:\n",iCase);
  295. scanf("%d",&Q);
  296. while(Q--)
  297. {
  298. scanf("%d%d",&u,&v);
  299. mroot(u);
  300. Access(v);
  301. Splay(v);
  302. printf("%d\n",ma[v]);
  303. }
  304. if(T > )printf("\n");
  305.  
  306. }
  307. return ;
  308. }

HDU 4718 The LCIS on the Tree (动态树LCT)的更多相关文章

  1. HDU 4718 The LCIS on the Tree(树链剖分)

    Problem Description For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i < ...

  2. HDU 4010 Query on The Trees(动态树LCT)

    Problem Description We have met so many problems on the tree, so today we will have a query problem ...

  3. [BZOJ2631]tree 动态树lct

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 5171  Solved: 1754[Submit][Status][Discus ...

  4. hdu 5398 动态树LCT

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

  5. hdu 5002 (动态树lct)

    Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  6. bzoj 2631: tree 动态树+常数优化

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1716  Solved: 576[Submit][Status] Descrip ...

  7. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  8. BZOJ 2631 tree 动态树(Link-Cut-Tree)

    题目大意:维护一种树形数据结构.支持下面操作: 1.树上两点之间的点权值+k. 2.删除一条边.添加一条边,保证加边之后还是一棵树. 3.树上两点之间点权值*k. 4.询问树上两点时间点的权值和. 思 ...

  9. LCT(link cut tree) 动态树

    模板参考:https://blog.csdn.net/saramanda/article/details/55253627 综合各位大大博客后整理的模板: #include<iostream&g ...

随机推荐

  1. python面向对象(七)属性方法的添加

    ​ 通常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.下来我就讲下添加属性和方法,同时也将下限值添加属性方法. 添加属性 ...

  2. 深度解析eclipse控制台

    第一个按钮:scroll lock 控制台在打印sql语句的时候会一直滚动,用这个按钮可以固定住控制台不乱跑; 第二个按钮:show console when standard out changes ...

  3. MySQL基础 - 视图

    创建视图: 假设要将posts表的前十条数据作为视图 mysql> CREATE VIEW view_test AS SELECT * FROM POSTS LIMIT 10; 使用: 可以把视 ...

  4. apachebench对网站进行并发测试

    ,安装apache ,打开cmd进入apache安装目录的bin目录(有ab.exe) ,执行ab命令 格式:ab -n -c http://localhost:80/test/test.php 说明 ...

  5. html-图片热点和网页划区

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. Numpy的简单用法

    Numpy的简单用法 import numpy as np 一.创建ndarray对象 列表转换成ndarray: >>> a = [1,2,3,4,5] >>> ...

  7. Oracle截取字符串和查找字符串

    oracle 截取字符(substr),检索字符位置(instr) case when then else end语句使用 收藏 常用函数:substr和instr 1.SUBSTR(string,s ...

  8. 在windows下的CLI模式下如何运行php文件

    https://blog.csdn.net/evkj2013/article/details/52313728 https://jingyan.baidu.com/article/da1091fb09 ...

  9. 《Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments》论文解读

    MADDPG原文链接 OpenAI bog DDPG链接 目录 一.摘要 二.效果展示 三.方法细节 问题分析 具体方法 伪代码 网络结构 四.实验结果 五.总结 附录 Proposition 1 一 ...

  10. spring 事务配置

    事务配置文档xml <!-- from the file 'context.xml' --> <?xml version="1.0" encoding=" ...