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 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.
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.
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.
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 }
人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想