H - The LCIS on the Tree HDU - 4718
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
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
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
Then output Q lines, each with an answer to the query.
There should be a blank line *BETWEEN* each test case.
Sample Input
5
1 2 3 4 5
1 1 3 3
3
1 5
4 5
2 5
Sample Output
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的更多相关文章
- 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 ...
- H - Partial Tree HDU - 5534 (背包)
题目链接: H - Partial Tree HDU - 5534 题目大意:首先是T组测试样例,然后n个点,然后给你度数分别为(1~n-1)对应的不同的权值,然后问你在这些点形成树的前提下的所能形 ...
- Binary Tree HDU - 5573 (思维)
题目链接: B - Binary Tree HDU - 5573 题目大意: 给定一颗二叉树,根结点权值为1,左孩子权值是父节点的两倍,右孩子是两倍+1: 给定 n 和 k,让你找一条从根结点走到第 ...
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- 【CodeForces】914 H. Ember and Storm's Tree Game 动态规划+排列组合
[题目]H. Ember and Storm's Tree Game [题意]Zsnuoの博客 [算法]动态规划+排列组合 [题解]题目本身其实并不难,但是大量干扰因素让题目显得很神秘. 参考:Zsn ...
- Minimal Ratio Tree HDU - 2489
Minimal Ratio Tree HDU - 2489 暴力枚举点,然后跑最小生成树得到这些点时的最小边权之和. 由于枚举的时候本来就是按照字典序的,不需要额外判. 错误原因:要求输出的结尾不能有 ...
- Color a Tree HDU - 6241
/* 十分巧妙的二分 题意选最少的点涂色 使得满足输入信息: 1 x的子树涂色数不少于y 2 x的子树外面涂色数不少于y 我们若是把2转化到子树内最多涂色多少 就可以维护这个最小和最大 如果我们二分出 ...
- 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 < ...
- hdu_4718_The LCIS on the Tree(树链剖分+线段树合并)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4718 题意:给你一棵树,每个节点有一个值,然后任给树上的两点,问这两点的最长连续递增区间是多少 题解: ...
随机推荐
- C#通过反射获得对象所有属性和值
C#获得对象的所有属性和值 public void GetPros() { UserInfo userInfo = new UserInfo(); userInfo.ID = ; userInfo.N ...
- js记录
--获取后缀名,结果 .jpg var extName = "/upload/head_img/20150902102539.jpg";var ta = extName.subst ...
- Luogu 2912 [USACO08OCT]牧场散步Pasture Walking
快乐树剖 #include<cstdio> #include<cstring> #include<algorithm> #define rd read() #def ...
- c++11 改进设计模式 Singleton模式
关于学习 <深入应用c++11>的代码笔记: c++11之前是这么实现的 template<typename T> class Singleton{ public: stati ...
- 使用kindeditor 4.1.7 编辑器 注意事项,上传图片失败 问题 ,
<script charset="utf-8" src="editor/kindeditor.js"></script> <scr ...
- window.load 和$(document).ready() 、window.load和body onload区别
1.执行时间 window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行. $(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕.2.编写个数不同 w ...
- String [] args是干什么的
我相信应该有不少人都疑惑,main后面的这个String [] args是干什么的呢?今天,巩固就为你们解密. 这是干什么的呢?先给大家一个简单定义(本人比较讨厌上来就举例子,因为 ...
- Shell获取当前路径
PRG="$0" while [ -h "$PRG" ]; do ls=`ls -ld "$PRG"` link=`expr "$ ...
- Deployment failure on Tomcat 6.x. Could not copy all resources to D:\...\webapps\eptInfo. If a file is locked, you can wait until the lock times out to redeploy, or stop the server and redeploy, or ma
tomcat服务并没有启动.工程中之前引了一个包,后来这个包被删除了,但是因为已经发布过这个工程了,所以classpath中就有这个包名了,这样发布的时候也会去找这个包但是已经不存在了,所以无copy ...
- qmake-how to
简单例子 假设已经实现如下程序: hello.cpphello.hmain.cpp 首先,使用编辑器,在上述文件目录下创建文件hello.pro.然后加入几行语句告诉qmake项目中的源文件和头文件. ...