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. async与await

    在方法上可以加 async,方法体内需要有 await,没有await的话,会出现warn警告.async单独出现是没有用的. await只能出现在Task前面.await Task的后面的代码会被封 ...

  2. 13.11.20 jquery 核心 siblings() 获得同类(不包含自己)循环所有,

    jquery 核心1.选择器,2. 创建dom 元素 3. jquery 执行时 4. 延迟执行 5. 循环 6. 计算长度.7.8 获得选择器和所在节点 9. 获得下标 10. 元素存放数据  11 ...

  3. C++ 面向对象基本释义

    public:子类继承,子类亦可以访问.本类函数可以访问,本类对象可以访问. private:子类继承,子类不可访问.本类(所有)函数以及友员函数可以访问,本类对象不可以访问. protect:子类继 ...

  4. sql中 in 、not in 、exists、not exists 用法和差别

    % 的一类. NOTIN:通过 NOTIN 关键字引入的子查询也返回一列零值或更多值. 以下查询查找没有出版过商业书籍的出版商的名称. SELECT pub_name FROM publishers ...

  5. Tomcat之Windows环境下配置多个服务器

    在应对多项目多端口的情况配置一个服务器是远不能满足开发条件的.例如微信公众号回调域名只接受80端口,而其他项目一般为默认的8080或者自定义的其他的端口. 废话多说,直入主题 准备条件:tomcat文 ...

  6. js中为什么非要alert一下下一步才会执行

    多数原因为界面ajax中动态添加的元素还没被添加上,就执行了js函数(js函数要调用动态元素),解决办法:ajax方法中添加 async:false,同步,作用为,在ajax执行完毕后才执行之后的js ...

  7. 使用Java实现网络爬虫

    网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 另外一些不常使用的名字还有蚂蚁.自动索引.模 ...

  8. 2018.10.13 bzoj1834: [ZJOI2010]network 网络扩容(最大流+费用流)

    传送门 网络流水题啊. 第一问直接放心跑最大流(本来还以为有什么tricktricktrick). 第二问就直接把原来的边(u,v,c,w)(u,v,c,w)(u,v,c,w)变成(u,v,c,0)( ...

  9. Object-C中方法

    //方法         //方法分了两种         //1.类方法,类调用,方法以+开头         //2.实例方法,对象调用,方法以-开头              //类方法和实例方 ...

  10. linux导出Excel The maximum column width for an individual cell is 255 characters

    linux环境到处Excel报错: The maximum column width for an individual cell is 255 characters 解决方案: for (int i ...