1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAXV = 100010; 8 const int MAXE = MAXV; 9 const int MAXT = MAXV << 2; 10 11 int lmaxi[MAXT], rmaxi[MAXT], mmaxi[MAXT]; 12 int lmaxd[MAXT], rmaxd[MAXT], mmaxd[MAXT]; 13 int val[MAXV], n, m, T; 14 15 int inc_ord[MAXV], dec_ord[MAXV], inc_rev[MAXV], dec_rev[MAXV]; 16 17 void init_inc_dec() { 18 for(int i = 1, t = 1; i <= n; ++i) { 19 if(t < i) t = i; 20 while(t < n && val[t] < val[t + 1]) ++t; 21 inc_ord[i] = t - i + 1; 22 } 23 for(int i = 1, t = 1; i <= n; ++i) { 24 if(t < i) t = i; 25 while(t < n && val[t] > val[t + 1]) ++t; 26 dec_ord[i] = t - i + 1; 27 } 28 for(int i = n, t = n; i > 0; --i) { 29 if(t > i) t = i; 30 while(t > 0 && val[t] < val[t - 1]) --t; 31 inc_rev[i] = i - t + 1; 32 } 33 for(int i = n, t = n; i > 0; --i) { 34 if(t > i) t = i; 35 while(t > 0 && val[t] > val[t - 1]) --t; 36 dec_rev[i] = i - t + 1; 37 } 38 } 39 40 int queryI(int x, int l, int r, int a, int b) { 41 if(a <= l && r <= b) { 42 return mmaxi[x]; 43 } else { 44 int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; 45 int ans = 0; 46 if(a <= mid) ans = max(ans, queryI(ll, l, mid, a, b)); 47 if(mid < b) ans = max(ans, queryI(rr, mid + 1, r, a, b)); 48 if(val[mid] < val[mid + 1]) { 49 ans = max(ans, min(rmaxi[ll], mid - a + 1) + min(lmaxi[rr], b - mid)); 50 } 51 return ans; 52 } 53 } 54 55 int queryD(int x, int l, int r, int a, int b) { 56 if(a <= l && r <= b) { 57 return mmaxd[x]; 58 } else { 59 int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; 60 int ans = 0; 61 if(a <= mid) ans = max(ans, queryD(ll, l, mid, a, b)); 62 if(mid < b) ans = max(ans, queryD(rr, mid + 1, r, a, b)); 63 if(val[mid] > val[mid + 1]) { 64 ans = max(ans, min(rmaxd[ll], mid - a + 1) + min(lmaxd[rr], b - mid)); 65 } 66 return ans; 67 } 68 } 69 70 void maintainI(int x, int l, int r) { 71 int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; 72 if(val[mid] < val[mid + 1]) { 73 lmaxi[x] = lmaxi[ll] + (lmaxi[ll] == mid - l + 1) * lmaxi[rr]; 74 rmaxi[x] = rmaxi[rr] + (rmaxi[rr] == r - mid) * rmaxi[ll]; 75 mmaxi[x] = max(rmaxi[ll] + lmaxi[rr], max(mmaxi[ll], mmaxi[rr])); 76 } else { 77 lmaxi[x] = lmaxi[ll]; 78 rmaxi[x] = rmaxi[rr]; 79 mmaxi[x] = max(mmaxi[ll], mmaxi[rr]); 80 } 81 } 82 83 void maintainD(int x, int l, int r) { 84 int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; 85 if(val[mid] > val[mid + 1]) { 86 lmaxd[x] = lmaxd[ll] + (lmaxd[ll] == mid - l + 1) * lmaxd[rr]; 87 rmaxd[x] = rmaxd[rr] + (rmaxd[rr] == r - mid) * rmaxd[ll]; 88 mmaxd[x] = max(rmaxd[ll] + lmaxd[rr], max(mmaxd[ll], mmaxd[rr])); 89 } else { 90 lmaxd[x] = lmaxd[ll]; 91 rmaxd[x] = rmaxd[rr]; 92 mmaxd[x] = max(mmaxd[ll], mmaxd[rr]); 93 } 94 } 95 96 void build(int x, int l, int r) { 97 if(l == r) { 98 lmaxi[x] = rmaxi[x] = mmaxi[x] = 1; 99 lmaxd[x] = rmaxd[x] = mmaxd[x] = 1; 100 } else { 101 int ll = x << 1, rr = ll | 1, mid = (l + r) >> 1; 102 build(ll, l, mid); 103 build(rr, mid + 1, r); 104 maintainI(x, l, r); 105 maintainD(x, l, r); 106 } 107 } 108 109 int v[MAXV]; 110 int fa[MAXV], son[MAXV], size[MAXV], tid[MAXV], top[MAXV], dep[MAXV]; 111 int head[MAXV], ecnt, dfs_clock; 112 int to[MAXE], next[MAXE]; 113 114 void init(int n) { 115 memset(head, -1, (n + 1) * sizeof(int)); 116 ecnt = dfs_clock = 0; 117 } 118 119 void add_edge(int u, int v) { 120 to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++; 121 } 122 123 void dfs_size(int u, int depth) { 124 size[u] = 1; son[u] = 0; dep[u] = depth; 125 int maxsize = 0; 126 for(int p = head[u]; ~p; p = next[p]) { 127 int &v = to[p]; 128 dfs_size(v, depth + 1); 129 size[u] += size[v]; 130 if(size[v] > maxsize) { 131 son[u] = v; 132 maxsize = size[v]; 133 } 134 } 135 } 136 137 void dfs_heavy_edge(int u, int ancestor) { 138 val[tid[u] = ++dfs_clock] = v[u]; 139 top[u] = ancestor; 140 if(son[u]) dfs_heavy_edge(son[u], ancestor); 141 for(int p = head[u]; ~p; p = next[p]) { 142 int &v = to[p]; 143 if(v == son[u]) continue; 144 dfs_heavy_edge(v, v); 145 } 146 } 147 148 int query(int x, int y) { 149 int res = 0, maxx = 0, prex = 0, maxy = 0, prey = 0; 150 while(top[x] != top[y]) { 151 if(dep[top[x]] > dep[top[y]]) { 152 int sz = dep[x] - dep[top[x]] + 1; 153 int up_ans = min(inc_rev[tid[x]], sz); 154 int down_ans = min(dec_ord[tid[top[x]]], sz); 155 res = max(res, queryD(1, 1, n, tid[top[x]], tid[x])); 156 if(prex && v[prex] >= v[x]) maxx = 0; 157 res = max(res, up_ans + maxx); 158 maxx = down_ans + (sz == down_ans) * maxx; 159 prex = top[x]; 160 x = fa[top[x]]; 161 } else { 162 int sz = dep[y] - dep[top[y]] + 1; 163 int up_ans = min(dec_rev[tid[y]], sz); 164 int down_ans = min(inc_ord[tid[top[y]]], sz); 165 res = max(res, queryI(1, 1, n, tid[top[y]], tid[y])); 166 if(prey && v[prey] <= v[y]) maxy = 0; 167 res = max(res, up_ans + maxy); 168 maxy = down_ans + (sz == down_ans) * maxy; 169 prey = top[y]; 170 y = fa[top[y]]; 171 } 172 } 173 if(dep[x] > dep[y]) { 174 int sz = dep[x] - dep[y] + 1; 175 int up_ans = min(inc_rev[tid[x]], sz); 176 int down_ans = min(dec_ord[tid[y]], sz); 177 res = max(res, queryD(1, 1, n, tid[y], tid[x])); 178 if(prex && v[prex] >= v[x]) maxx = 0; 179 if(prey && v[prey] <= v[y]) maxy = 0; 180 res = max(res, up_ans + maxx); 181 res = max(res, down_ans + maxy); 182 if(up_ans == sz) res = max(res, maxx + up_ans + maxy); 183 } else { 184 int sz = dep[y] - dep[x] + 1; 185 int up_ans = min(dec_rev[tid[y]], sz); 186 int down_ans = min(inc_ord[tid[x]], sz); 187 res = max(res, queryI(1, 1, n, tid[x], tid[y])); 188 if(prex && v[prex] >= v[x]) maxx = 0; 189 if(prey && v[prey] <= v[y]) maxy = 0; 190 res = max(res, down_ans + maxx); 191 res = max(res, up_ans + maxy); 192 if(up_ans == sz) res = max(res, maxx + up_ans + maxy); 193 } 194 return res; 195 } 196 197 int main() { 198 scanf("%d", &T); 199 for(int t = 1; t <= T; ++t) { 200 scanf("%d", &n); 201 init(n); 202 for(int i = 1; i <= n; ++i) scanf("%d", &v[i]); 203 for(int i = 2; i <= n; ++i) { 204 scanf("%d", &fa[i]); 205 add_edge(fa[i], i); 206 } 207 dfs_size(1, 1); 208 dfs_heavy_edge(1, 1); 209 build(1, 1, n); 210 init_inc_dec(); 211 printf("Case #%d:\n", t); 212 scanf("%d", &m); 213 while(m--) { 214 int u, v; 215 scanf("%d%d", &u, &v); 216 printf("%d\n", query(u, v)); 217 } 218 if(t != T) puts(""); 219 } 220 }