The LCIs on the Tree Time limit:6000/3000 MS (java/others) Memory limit:65535/65535 K (java/others)
Total submission (s): 533 Accepted Submission (s): 167
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 aCIS(Continuous increasing subsequence). The longestCISOf a sequence is called theLCIs(Longest continuous increasing subsequence).
Now we consider a tree rooted at node 1. Nodes has the values. We have a Q queries, each with a nodes U and v. You had to find the shortest path from u to v. and write down each nodes ' value of the path, from U to V, inclusive. Then you'll get a sequence, and please show us the length of itsLCIs.
Input the first line has a number T (T <=), indicating the number of test cases.
For each test case, the first line is a number n (n <= 5), and 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 I s the root and would have no father.
Then comes a number Q, it is the number of queries. (Q <= 10 5)
For next Q lines, each with a 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 a answer to the query.
There should is 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 ACM/ICPC Asia Regional online--warmup2
Recommend zhuyuanchen520 | We have carefully selected several similar problems for you:5099 5098 5097 5096 5095
Maximum length of the longest continuous increment substring on a path
Splay maintain such a thing
Leftmost value, rightmost value
Leftmost continuous rising length, leftmost continuous descent length
Right-most continuous rising length, right-most continuous descent length
Longest ascending sub-string length of interval, longest descending substring length in interval
Interval size
Then update the time to be more troublesome ~ ~ ~ is the merger of the three nodes, line tree words two nodes will be OK
It's either the value of the left or right child, and the two subtrees and the root can be linked together.
I wrote it harder.
#pragma COMMENT (linker, "/stack:102400000,102400000") #include <cstdio> #include <cstring> #include <
Algorithm> #include <iostream> using namespace std;
#define MAXN 500007 struct node{Node *fa,*ch[2];
BOOL Rev,root;
int val,size;
int Ulenl,ulenr,uans;
int Dlenl,dlenr,dans;
int lnum,rnum;
};
Node POOL[MAXN];
Node *NIL,*TREE[MAXN];
int cnt = 0;
void init () {cnt = 1;
Nil = tree[0] = pool;
NIL->ULENL = nil->dlenl = Nil->ulenr = Nil->dlenr = 0;
Nil->uans = Nil->dans = 0;
nil->size = 0;
} inline Node *newnode (int val,node *f) {pool[cnt].fa = f;
Pool[cnt].ch[0] = pool[cnt].ch[1] = nil;
Pool[cnt].rev = false;
Pool[cnt].root = true;
Pool[cnt].rnum = val;
Pool[cnt].lnum = val;
Pool[cnt].val = val;
POOL[CNT].ULENL = 1;
Pool[cnt].ulenr = 1;
Pool[cnt].uans = 1;
POOL[CNT].DLENL = 1;
Pool[cnt].dlenr = 1;
Pool[cnt].dans = 1;
Pool[cnt].size = 1; Return &pool[cnt++];
//splay up update information void Update (node *x) {Node *l = X->ch[0],*r = x->ch[1];
X->size = l->size + 1;
X->rnum = X->lnum = x->val;
X->ULENL = X->ulenr = x->dlenl = X->dlenr = 1;
X->uans = X->dans = 1;
if (l! = nil) {if (X->val > L->rnum) x->ulenr = l->ulenr+1;
if (X->val < l->rnum) X->dlenr = l->dlenr+1;
if ((l->ulenl = = l->size) && x->val > L->rnum) x->ulenl = l->ulenl+1;
else x->ulenl = l->ulenl;
if ((l->dlenl = = l->size) && x->val < l->rnum) X->dlenl = l->dlenl+1;
else x->dlenl = l->dlenl;
X->uans = max (X->uans,l->uans);
X->dans = max (X->dans,l->dans);
X->lnum = l->lnum;
} X->uans = max (X->UANS,X->ULENL);
X->uans = max (X->UANS,X->ULENR); X->dans = Max (x->dans,x->dlenl);
X->dans = max (X->DANS,X->DLENR);
if (r! = nil) {if (X->rnum < r->lnum) X->uans = max (X->UANS,X->ULENR+R->ULENL);
if (X->rnum > r->lnum) X->dans = max (X->DANS,X->DLENR+R->DLENL);
if (X->rnum < R->lnum && (x->ulenl = = x->size)) X->ulenl + = r->ulenl;
if (X->rnum > R->lnum && (x->dlenl = = x->size)) X->dlenl + = r->dlenl;
if (X->rnum < R->lnum && (R->ulenr = = r->size)) X->ulenr + = r->ulenr;
else X->ulenr = r->ulenr;
if (X->rnum > R->lnum && (r->dlenr = = r->size)) X->dlenr + = r->dlenr;
else X->dlenr = r->dlenr;
X->uans = max (X->uans,r->uans);
X->dans = max (X->dans,r->dans);
X->rnum = r->rnum;
} x->size + = r->size;
X->uans = max (X->UANS,X->ULENL); X->uans = Max (x-> uans,x->ulenr);
X->dans = max (X->DANS,X->DLENL);
X->dans = max (X->DANS,X->DLENR);
cout<<x->dans<< "" <<x->uans<<endl;}
void Update_rev (Node *x) {if (x = = nil) return;
X->rev =!x->rev;
Swap (x->ch[0],x->ch[1]);
Swap (X->rnum, x->lnum);
Swap (X->ULENL,X->DLENR);
Swap (X->DLENL,X->ULENR);
Swap (X->uans, X->dans);
}//splay Push message void Pushdown (Node *x) {if (X->rev! = False) {Update_rev (x->ch[0]);
Update_rev (x->ch[1]);
X->rev = false;
}}//splay push information under root-->x path void push (Node *x) {if (!x->root) push (X->FA);
Pushdown (x);
}//Rotate node X to Splay's father's position void Rotate (node *x) {node *f = x->fa, *ff = f->fa;
int t = (f->ch[1] = = x);
if (f->root) X->root = True, F->root = false;
else ff->ch[ff->ch[1] = = f] = x;
X->FA = FF;
F->ch[t] = x->ch[t^1]; X->ch[t^1]->fa = f;
X->ch[t^1] = f;
F->FA = x;
Update (f);
}//To rotate the node x to the root of the splay where x is located void splay (Node *x) {push (x);
Node *f, *ff;
while (!x->root) {f = X->fa,ff = f->fa;
if (!f->root) if ((ff->ch[1] = = f) && (f->ch[1] = = x)) rotate (f);
else rotate (x);
Rotate (x);
} update (x);
}//The path of x to the root of the tree is made into one path node *access (node *x) {node *y = nil;
while (x! = nil) {splay (x);
X->ch[1]->root = true;
(x->ch[1] = y)->root = false;
Update (x);
y = x;
x = x->fa;
} return y;
}//Turn node x into root void be_root (node *x) {access (x);
Splay (x);
Update_rev (x);
} struct edge{int v,next;};
Edge EDGE[2*MAXN];
int head[maxn],ecnt;
int VALUE[MAXN];
void Add_edge (int u,int v) {edge[ecnt].v = v;
Edge[ecnt].next = Head[u];
Head[u] = ecnt++;
EDGE[ECNT].V = u;
Edge[ecnt].next = Head[v];
HEAD[V] = ecnt++; } void Dfs (int u,intf) {Tree[u] = NewNode (value[u],tree[f]);
for (int i = head[u]; I! = -1;i = Edge[i].next) {if (edge[i].v = = f) Continue;
DFS (EDGE[I].V,U);
}} int main () {int t,tt=0,n,w,x,y,v,q;
Node*p;
scanf ("%d", &t);
while (t--) {if (TT > 0) printf ("\ n");
printf ("Case #%d:\n", ++TT);
scanf ("%d", &n);
memset (head,-1,sizeof (head));
ecnt = 0;
Init ();
for (int i = 1;i <= n; i++) scanf ("%d", &value[i]);
for (int i = 2; I <= n; i++) {scanf ("%d", &y);
Add_edge (I,y);
} dfs (1,0);
scanf ("%d", &q);
while (q--) {scanf ("%d%d", &x,&y);
Be_root (Tree[x]);
p = Access (Tree[y]);
printf ("%d\n", P->uans);
}} return 0;
}