Hdu 4718 The LCIS on the Tree 动态树 LCT
2014-11-06 23:00
417 查看
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 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
2013 ACM/ICPC Asia Regional Online —— Warmup2
Recommend
zhuyuanchen520 | We have carefully selected several similar problems for you: 5099 5098 5097 5096 5095
求路径上最长的连续递增子串的最大长度
splay维护这样一个东西
最左边的值,最右边的值
最左边连续上升长度,最左边连续下降长度
最右边连续上升长度,最右边连续下降长度
区间最长上升子串长,区间最长下降子串长
区间大小
然后update的时候比较麻烦~~~是三个结点的合并,线段树的话两个结点就行了
反正是要么是左右孩子的值中的最值,两颗子树和根是可以连起来的
我写的比较费劲~
#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向上更新信息 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下推信息 void pushdown(Node *x){ if(x->rev != false){ update_rev(x->ch[0]); update_rev(x->ch[1]); x->rev = false; } } //splay在root-->x的路径下推信息 void push(Node *x){ if(!x->root) push(x->fa); pushdown(x); } //将结点x旋转至splay中父亲的位置 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); } //将结点x旋转至x所在splay的根位置 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); } //将x到树根的路径并成一条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; } //将结点x变成树根 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,int f){ 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; }
相关文章推荐
- HDU 4718 The LCIS on the Tree (动态树LCT)
- hdu-4718:The LCIS on the Tree(树链剖分+区间合并)
- HDU 4718 The LCIS on the Tree
- hdu 4718 The LCIS on the Tree
- HDU 4718 The LCIS on the Tree(树链剖分+线段树)
- lca(HDU 4718,The LCIS on the Tree)
- HDU 4718 The LCIS on the Tree (树链剖分 + 线段树区间合并)
- hdu_4718_The LCIS on the Tree(树链剖分+线段树合并)
- HDU 4718 The LCIS on the Tree (树链剖分+线段树区间合并)
- HDU 4718 The LCIS on the Tree(树链剖分)
- HDU 4718 The LCIS on the Tree 树上路径倍增
- 【HDU 4718】 The LCIS on the Tree 【树链剖分+线段树合并】
- hdu_4718_The LCIS on the Tree(树链剖分+线段树合并)
- 【树链剖分】 HDOJ 4718 The LCIS on the Tree
- HDU 4010 Query on The Trees(动态树LCT)
- HDU4718 The LCIS on the Tree(LCT)
- 【HDOJ】4718 The LCIS on the Tree 树链剖分
- HDU 4010 Query on the tree LCT模板题
- 动态树(LCT):HDU 4010 Query on The Trees
- 【HDU】4010 Query on The Trees 动态树之Link Cut Tree(LCT)