The LCIS on the Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 1615    Accepted Submission(s): 457

题目链接

https://vjudge.net/problem/UVA-12655

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

题意

在一棵树上,每次求一条路径最长连续上升子序列。

题解

一开始看错题,以为求最长上升子序列,然后想了好久毫无思路,一看题解发现原来我看错题了。

连续的话就不难了。

树链剖分,然后线段树记录一下该区间最长上升子序列,左端点开始的最长上升子序列长度,右端点。。。

反正就是考虑如果知道左子树和右子树的信息,如何合并。显然合并就是中间可能延长,其他的都一样。

但是在树上,x-->lca(x,y) 和 lca(x,y)-->是不一样的,x-->lca(x,y)需要求最长下降子序列,然后就是一对细节需要处理,具体看代码吧。

代码

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 500050
struct Tree{int l,r,lb,rb,lI,rI,lD,rD,Imx,Dmx;}tr[N<<];
struct Edge{int from,to,s;}edges[N<<];
int n,m,cas,w[N];
int tot,last[N];
int cnt,fa[N],dp[N],size[N],son[N],rk[N],kth[N],top[N];
template<typename T>void read(T&x)
{
ll k=; char c=getchar();
x=;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit();
while(isdigit(c))x=x*+c-'',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void AddEdge(int x,int y)
{
edges[++tot]=Edge{x,y,last[x]};
last[x]=tot;
}
void dfs1(int x,int pre)
{
fa[x]=pre;
dp[x]=dp[pre]+;
size[x]=;
son[x]=;
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dfs1(e.to,x);
size[x]+=size[e.to];
if(size[e.to]>size[son[x]])son[x]=e.to;
}
}
void dfs2(int x,int y)
{
rk[x]=++cnt;
kth[cnt]=x;
top[x]=y;
if (son[x]==)return;
dfs2(son[x],y);
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==fa[x]||e.to==son[x])continue;
dfs2(e.to,e.to);
}
}
void init(Tree &a){a=Tree{,,,,,,,,,};}
template<typename T>void he(T &c,T a, T b)
{
if (a.Imx==){c=b;return;}
if (b.Imx==){c=a;return;}
c.l=a.l; c.r=b.r;
int lena=a.r-a.l+,lenb=b.r-b.l+;
c.lb=a.lb; c.rb=b.rb;
c.lI=lena==a.lI&&a.rb<b.lb?lena+b.lI:a.lI;
c.lD=lena==a.lD&&a.rb>b.lb?lena+b.lD:a.lD;
c.rI=lenb==b.rI&&a.rb<b.lb?lenb+a.rI:b.rI;
c.rD=lenb==b.rD&&a.rb>b.lb?lenb+a.rD:b.rD;
c.Imx=max(a.Imx,b.Imx);
c.Imx=max(c.Imx,a.rb<b.lb?a.rI+b.lI:);
c.Dmx=max(a.Dmx,b.Dmx);
c.Dmx=max(c.Dmx,a.rb>b.lb?a.rD+b.lD:);
}
void bt(int x,int l,int r)
{
tr[x].l=l; tr[x].r=r;
if (l==r)
{
tr[x]={l,r,w[kth[l]],w[kth[l]],,,,,,};
return;
}
int mid=(l+r)>>;
bt(x<<,l,mid);
bt(x<<|,mid+,r);
he(tr[x],tr[x<<],tr[x<<|]);
}
Tree query(int x,int l,int r)
{
if (l<=tr[x].l&&tr[x].r<=r)
return tr[x];
int mid=(tr[x].l+tr[x].r)>>;
Tree tp1,tp2,tp; init(tp1); init(tp2);
if (l<=mid)tp1=query(x<<,l,r);
if (mid<r)tp2=query(x<<|,l,r);
he(tp,tp1,tp2);
return tp;
}
int get_max(int x,int y)
{
int fx=top[x],fy=top[y],ans=;
Tree tpx,tpy,tp;
init(tpx); init(tpy);
while(fx!=fy)
{
if (dp[fx]>dp[fy])
{
tp=query(,rk[fx],rk[x]);
he(tpx,tp,tpx);
x=fa[fx]; fx=top[x];
}
else
{
tp=query(,rk[fy],rk[y]);
he(tpy,tp,tpy);
y=fa[fy]; fy=top[y];
}
}
if (dp[x]>dp[y])
{
tp=query(,rk[y],rk[x]);
he(tpx,tp,tpx);
}
else
{
tp=query(,rk[x],rk[y]);
he(tpy,tp,tpy);
}
ans=max(tpx.Dmx,tpy.Imx);
ans=max(ans,tpx.lb<tpy.lb?tpx.lD+tpy.lI:);
return ans;
}
void work()
{
if (cas)printf("\n");
printf("Case #%d:\n",++cas);
read(n);
for(int i=;i<=n;i++)read(w[i]);
for(int i=;i<=n;i++)
{
int x;
read(x);
AddEdge(x,i);
}
dfs1(,);
dfs2(,);
bt(,,n);
read(m);
for(int i=;i<=m;i++)
{
int x,y;
read(x); read(y);
printf("%d\n",get_max(x,y));
}
}
void clear()
{
cnt=; tot=;
memset(last,,sizeof(last));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
int q;
read(q);
while(q--)
{
clear();
work();
}
}

H - The LCIS on the Tree HDU - 4718的更多相关文章

  1. 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/Oth ...

  2. H - Partial Tree HDU - 5534 (背包)

    题目链接: H - Partial Tree  HDU - 5534 题目大意:首先是T组测试样例,然后n个点,然后给你度数分别为(1~n-1)对应的不同的权值,然后问你在这些点形成树的前提下的所能形 ...

  3. Binary Tree HDU - 5573 (思维)

    题目链接: B - Binary Tree  HDU - 5573 题目大意: 给定一颗二叉树,根结点权值为1,左孩子权值是父节点的两倍,右孩子是两倍+1: 给定 n 和 k,让你找一条从根结点走到第 ...

  4. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  5. 【CodeForces】914 H. Ember and Storm's Tree Game 动态规划+排列组合

    [题目]H. Ember and Storm's Tree Game [题意]Zsnuoの博客 [算法]动态规划+排列组合 [题解]题目本身其实并不难,但是大量干扰因素让题目显得很神秘. 参考:Zsn ...

  6. Minimal Ratio Tree HDU - 2489

    Minimal Ratio Tree HDU - 2489 暴力枚举点,然后跑最小生成树得到这些点时的最小边权之和. 由于枚举的时候本来就是按照字典序的,不需要额外判. 错误原因:要求输出的结尾不能有 ...

  7. Color a Tree HDU - 6241

    /* 十分巧妙的二分 题意选最少的点涂色 使得满足输入信息: 1 x的子树涂色数不少于y 2 x的子树外面涂色数不少于y 我们若是把2转化到子树内最多涂色多少 就可以维护这个最小和最大 如果我们二分出 ...

  8. HDU 4718 The LCIS on the Tree(树链剖分)

    Problem Description For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i < ...

  9. hdu_4718_The LCIS on the Tree(树链剖分+线段树合并)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4718 题意:给你一棵树,每个节点有一个值,然后任给树上的两点,问这两点的最长连续递增区间是多少 题解: ...

随机推荐

  1. 史上最全的Android开发学习教程集锦【初学者】

    根据Google的报告,截止2017年5月为止,Android活跃用户已超过20亿,并还在持续增长中.Android系统在几个主要的市场上已超过了iOS系统,特别是在美国,欧洲和日本,然而苹果确实在中 ...

  2. Mockplus推出真正无限制终身版,做原型就要一辈子!

    如今提到原型工具,各位设计师和PM爸爸们一定不会对Mockplus感到陌生吧?事实上,从一开始的默默无闻,到在UXPA大赛上崭露头角,再到被Adobe XD 列为主要竞品,如今,摩客君已经在全球范围内 ...

  3. css样式记忆

    text-indent: 2em;   //开头空两格: display : none;    //隐藏元素 background:#CCC;  //背景颜色 background: url(imag ...

  4. 47 On Interpersonal Relationship 关于人际关系

    47 On Interpersonal Relationship 关于人际关系 ①Since we are social beings, the quality of our lives depend ...

  5. Django的路由层(2)

    https://www.cnblogs.com/yuanchenqi/articles/8931472.html django2.0版的path Django默认支持以下5个转化器: str,匹配除了 ...

  6. gulp布局构建小结

    一.工具选择CSS预处理语言LESS 构建工具gulp(基于node环境)gulp插件:gulp-connect——主要是用来运行一个webserver npm install --save-dev ...

  7. (最小生成树) Jungle Roads -- POJ -- 1251

    链接: http://poj.org/problem?id=1251 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2177 ...

  8. yum 常用命令

    yum是一个用于管理rpm包的后台程序,用python写成,可以非常方便的解决rpm的依赖关系.在建立好yum服务器后,yum客户端可以通过 http.ftp方式获得软件包,并使用方便的命令直接管理. ...

  9. D3_book 11.1 pie

    <!-- pie example --> <!DOCTYPE html> <meta charset="utf-8"> <style> ...

  10. cocos studio

    用了几天,和之前用的cocos creator以及unity的编辑器一对比,很多地方都挺反人类的哈... 拖拽和放大场景元素竟然还要切换一下编辑模式... 移动场景元素竟然没有单独控制x或者y方向的移 ...