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/Others)
Total Submission(s): 175    Accepted Submission(s): 40


Problem Description
For a sequence S 1, S 2, ... , S N, and a pair of integers (i, j), if 1 <= i <= j <= N and S i < S i+1 < S i+2 < ... < S j-1 < S j , then the sequence S i, S i+1, ... , S j 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 <= 10 5), the number of nodes in the tree.
The second line comes with N numbers v1, v2, v3 ... , v N, describing the value of node 1 to node N. (1 <= v i <= 10 9)
The third line comes with N - 1 numbers p 2, p 3, p 4 ... , p N, 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 <= 10 5)
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 = 100010;
 41 int ch[MAXN][2], 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][0],ch[r][1]);
 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] ^= 1;
 58 }
 59 void push_down(int r)
 60 {
 61     if(rev[r])
 62     {
 63         Update_Rev(ch[r][0]);
 64         Update_Rev(ch[r][1]);
 65         rev[r] = 0;
 66     }
 67 }
 68 void push_up(int r)
 69 {
 70     size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
 71     if(ch[r][0])lv[r] = lv[ch[r][0]];
 72     else lv[r] = key[r];
 73     if(ch[r][1])rv[r] = rv[ch[r][1]];
 74     else rv[r] = key[r];
 75 
 76     if(ch[r][0] == 0)
 77     {
 78         if(ch[r][1] == 0)
 79         {
 80             la[r] = 1;
 81             ls[r] = 1;
 82         }
 83         else
 84         {
 85             if(key[r] < lv[ch[r][1]])
 86                 la[r] = 1+la[ch[r][1]];
 87             else la[r] = 1;
 88             if(key[r] > lv[ch[r][1]])
 89                 ls[r] = 1 + ls[ch[r][1]];
 90             else ls[r] = 1;
 91         }
 92     }
 93     else
 94     {
 95         if(la[ch[r][0]] == size[ch[r][0]])
 96         {
 97             if(rv[ch[r][0]] < key[r])
 98             {
 99                 if(ch[r][1] == 0)
100                     la[r] = la[ch[r][0]] + 1;
101                 else
102                 {
103                     if(key[r] < lv[ch[r][1]])
104                         la[r] = la[ch[r][0]] + 1 + la[ch[r][1]];
105                     else la[r] = la[ch[r][0]] + 1;
106                 }
107             }
108             else la[r] = la[ch[r][0]];
109         }
110         else la[r] = la[ch[r][0]];
111 
112         if(ls[ch[r][0]] == size[ch[r][0]])
113         {
114             if(rv[ch[r][0]] > key[r])
115             {
116                 if(ch[r][1] == 0)
117                     ls[r] = ls[ch[r][0]] + 1;
118                 else
119                 {
120                     if(key[r] > lv[ch[r][1]])
121                         ls[r] = ls[ch[r][0]] + 1 + ls[ch[r][1]];
122                     else ls[r] = ls[ch[r][0]] + 1;
123                 }
124             }
125             else ls[r] = ls[ch[r][0]];
126         }
127         else ls[r] = ls[ch[r][0]];
128 
129     }
130 
131     if(ch[r][1] == 0)
132     {
133         if(ch[r][0] == 0)
134         {
135             ra[r] = 1;
136             rs[r] = 1;
137         }
138         else
139         {
140             if(key[r] > rv[ch[r][0]])
141                 ra[r] = ra[ch[r][0]] + 1;
142             else ra[r] = 1;
143             if(key[r] < rv[ch[r][0]])
144                 rs[r] = rs[ch[r][0]] + 1;
145             else rs[r] = 1;
146         }
147     }
148     else
149     {
150         if(ra[ch[r][1]] == size[ch[r][1]])
151         {
152             if(key[r] < lv[ch[r][1]])
153             {
154                 if(ch[r][0] == 0)
155                     ra[r] = ra[ch[r][1]] + 1;
156                 else
157                 {
158                     if(key[r] > rv[ch[r][0]])
159                         ra[r] = ra[ch[r][0]] + 1 + ra[ch[r][1]];
160                     else ra[r] = ra[ch[r][1]] + 1;
161                 }
162             }
163             else ra[r] = ra[ch[r][1]];
164         }
165         else ra[r] = ra[ch[r][1]];
166 
167         if(rs[ch[r][1]] == size[ch[r][1]])
168         {
169             if(key[r] > lv[ch[r][1]])
170             {
171                 if(ch[r][0] == 0)
172                     rs[r] = rs[ch[r][1]] + 1;
173                 else
174                 {
175                     if(key[r] < rv[ch[r][0]])
176                         rs[r] = rs[ch[r][0]] + 1 + rs[ch[r][1]];
177                     else rs[r] = rs[ch[r][1]] + 1;
178                 }
179             }
180             else rs[r] = rs[ch[r][1]];
181         }
182         else rs[r] = rs[ch[r][1]];
183 
184     }
185 
186 
187 
188     ma[r] = max(ma[ch[r][0]],ma[ch[r][1]]);
189     ms[r] = max(ms[ch[r][0]],ms[ch[r][1]]);
190     int tmp = 1;
191     if(ch[r][0] && key[r] > rv[ch[r][0]])
192         tmp += ra[ch[r][0]];
193     if(ch[r][1] && key[r] < lv[ch[r][1]])
194         tmp += la[ch[r][1]];
195     ma[r] = max(ma[r],tmp);
196     tmp= 1;
197     if(ch[r][0] && key[r] < rv[ch[r][0]])
198         tmp += rs[ch[r][0]];
199     if(ch[r][1] && key[r] > lv[ch[r][1]])
200         tmp += ls[ch[r][1]];
201     ms[r] = max(ms[r],tmp);
202 
203 }
204 void Rotate(int x)
205 {
206     int y = pre[x], kind = ch[y][1]==x;
207     ch[y][kind] = ch[x][!kind];
208     pre[ch[y][kind]] = y;
209     pre[x] = pre[y];
210     pre[y] = x;
211     ch[x][!kind] = y;
212     if(rt[y])
213         rt[y] = false, rt[x] = true;
214     else
215         ch[pre[x]][ch[pre[x]][1]==y] = x;
216     push_up(y);
217 }
218 void P(int r)
219 {
220     if(!rt[r])P(pre[r]);
221     push_down(r);
222 }
223 void Splay(int r)
224 {
225     P(r);
226     while( !rt[r] )
227     {
228         int f = pre[r], ff = pre[f];
229         if(rt[f])
230             Rotate(r);
231         else if( (ch[ff][1]==f) == (ch[f][1]==r) )
232             Rotate(f), Rotate(r);
233         else
234             Rotate(r), Rotate(r);
235     }
236     push_up(r);
237 }
238 int Access(int x)
239 {
240     int y = 0;
241     for( ; x ; x = pre[y=x])
242     {
243         Splay(x);
244         rt[ch[x][1]] = true, rt[ch[x][1]=y] = false;
245         push_up(x);
246     }
247     return y;
248 }
249 int mroot(int r)
250 {
251     Access(r);
252     Splay(r);
253     Update_Rev(r);
254 }
255 
256 
257 int main()
258 {
259     //freopen("in.txt","r",stdin);
260     //freopen("out.txt","w",stdout);
261     int T;
262     int n;
263     int Q;
264     int u,v;
265     scanf("%d",&T);
266     int iCase = 0;
267     while(T--)
268     {
269         iCase++;
270         scanf("%d",&n);
271         for(int i = 1;i <= n;i++)
272         {
273             pre[i] = 0;
274             ch[i][0] = ch[i][1] = 0;
275             rev[i] = 0;
276             rt[i] = true;
277             la[i] = ra[i] = ma[i] = 1;
278             ls[i] = rs[i] = ms[i] = 1;
279             size[i] = 1;
280         }
281         pre[0] = 0;
282         ch[0][0] = ch[0][0] = 0;
283         rev[0] = 0;
284         rt[0] = true;
285         la[0] = ra[0] = ma[0] = 0;
286         ls[0] = rs[0] = ms[0] = 0;
287         size[0] = 0;
288 
289         for(int i = 1;i <= n;i++)
290         {
291             scanf("%d",&key[i]);
292             lv[i] = rv[i] = key[i];
293         }
294         for(int i = 2;i <= n;i++)
295             scanf("%d",&pre[i]);
296 
297 
298         printf("Case #%d:\n",iCase);
299         scanf("%d",&Q);
300         while(Q--)
301         {
302             scanf("%d%d",&u,&v);
303             mroot(u);
304             Access(v);
305             Splay(v);
306             printf("%d\n",ma[v]);
307         }
308         if(T > 0)printf("\n");
309 
310     }
311     return 0;
312 }

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值