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. 观察者模式 DataObserver

    DatasetObserver是Observer的一个子类 针对于adapter设计的 当调用notifydatasetchanged的时候就会触发回调的方法 adapter.registerObse ...

  2. springmvc使用包装的pojo接收商品信息的查询条件

    1.包装对象定义如下: 定义Items对象,并对其定义set和get方法. public class QueryVo { private Items items; public Items getIt ...

  3. 21个ui设计技巧,让你的设计不落伍

    1.功能性极简主义 不少移动端APP和网站开始基于极简主义设计风来设计,而极简主义本身并非关注所有的信息,而是通过减少非关键信息来突出特定的内容,它是有着极强的功能性和偏向的.它有着如下的特征: ・简 ...

  4. <asp:RadioButton> 选项判断

    小菜在项目中遇到一个<asp:RadioButton> 选择之后,让其控制其他标签显示或者隐藏的问题.记录以备忘记之需! <html xmlns="http://www.w ...

  5. 着重基础之—Spring Boot 编写自己的过滤器

    Spring Boot 编写自己的"过滤器" 又好久没有写博客进行总结了,说实话,就是 "懒",懒得总结,懒得动.之所以写这篇博客,是因为最近对接公司SSO服务的时候,需要自定义拦 ...

  6. Part 1 - Getting Started(1-3)

    https://simpleisbetterthancomplex.com/series/2017/09/04/a-complete-beginners-guide-to-django-part-1. ...

  7. [转载][翻译]Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[2]

    Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其 ...

  8. web页面中a标签下载文件包含中文下载失败的解决

    之前用到的文件下载,文件名都是时间戳的形式或者英文名.下载没有问题.后来附件有中文后写在页面是下面效果,点击下载,下载失败. 对应链接拿出来.是如下效果 之前用了各种其他办法都不理想,比如转义什么的. ...

  9. Java_得到GET和POST请求URL和参数列表

    一. 获取URL: getRequestURL()(还有个getRequestURI(),只取后面部分) 二. 获取参数列表: 1.getQueryString() 只适用于GET,比如客户端发送ht ...

  10. 20155218 2016-2017-2 《Java程序设计》第10周学习总结

    20155218 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 一个IP地址可以对应多个域名,一个域名只能对应一个IP地址. 在网络通讯中,第一次主动发起 ...