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 题意:给你一棵树,每个节点有一个值,然后任给树上的两点,问这两点的最长连续递增区间是多少 题解: ...
随机推荐
- Navicat Premium11连接Oracle出现ORA-28547:connection to server failed
环境描述:本地Oracle正常安装,中途没有出现任何异常.确保Oracle的主要服务都启动了.1.OracleServiceORCL2.OracleOraDb11g_home1TNSListener ...
- php 使用html5 XHR2 上传文件 进度显示
思路:只要我们知道上传文件的总大小,还有上传过程中上传文件的大小,那么就可以实现进度显示了. 在html5中,XMLHttpRequest对象,传送数据的时候,progress事件用来返回进度信息. ...
- URL统一资源定位符的组成
URL:Uniform Resource Locator统一资源定位符 用于定位网络上我们需要访问的资源 组成:协议名称+域名+路径+资源的名称.如:https://img13.360img.com/ ...
- git保护进程
https://github.com/Mattiwatti/PPLKiller 去掉进程保护内核级
- TF Boys (TensorFlow Boys ) 养成记(二): TensorFlow 数据读取
TensorFlow 的 How-Tos,讲解了这么几点: 1. 变量:创建,初始化,保存,加载,共享: 2. TensorFlow 的可视化学习,(r0.12版本后,加入了Embedding Vis ...
- 2018.10.04 NOIP模拟 航班(tarjan+树形dp)
传送门 考场上自己yy了一个双连通只有40分. 然后换根dp求最长路就行了. 代码
- 2018.09.25 poj3070 Fibonacci(矩阵快速幂)
传送门 矩阵快速幂板题,写一道来练练手. 这一次在poj做题总算没忘了改万能库. 代码: #include<iostream> #include<cstdio> #define ...
- hdu-1163(九余数定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1163 思路: 九余数定理:一个数对九取余的结果叫做九余数, 一个数的各个位数相加的得到的小于10的数也 ...
- MySQL通过游标来实现通过查询记录集循环
/*我们有时候会遇到需要对 从A表查询的结果集S_S 的记录 进行遍历并做一些操作(如插入),且这些操作需要的数据或许部分来自S_S集合*//*临时存储过程,没办法,不能直接在查询窗口做这些事.*/d ...
- 配置 struts2 时掉进 web.xml 的坑
这个声明不好用 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quo ...