题目大意:

给定n个点 每个点都有权值

接下来给定树的n条边 第 i 个数 a[i] 表示 i+1到a[i]之间 有一条边

给定q q个询问 每次询问给出 x y 求x到y的最长上升子序列的长度

题解 https://blog.csdn.net/forever_wjs/article/details/52088861

明确几个变量的定义之后 更新部分一看就懂 就不注释了

需要特别提到的是

我们每次合并区间是合并 新的要合并的区间(左子区间) 和 底部已合并好的区间(右子区间)

而我们在查询过程中两个点由底部不断向LCA逼近

这样当x和y逼近到LCA时 x和y对应区间的方向是 由LCA到x 由LCA到y 这样的两个区间

所以这两个区间不能进行合并 因为起点相同

所以 就应该利用

x对应区间的 由右端点始下降的LCIS 和 右端点的值

y对应区间的 有左端点始上升的LCIS 和 左端点的值

再更新一次答案

#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(i,j) memset(i,j,sizeof(i))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define root 1,n,1 const int maxn=1e5+;
int n, q, w[maxn]; struct IntervalTree {
struct EDGE { int to,ne; }e[maxn<<];
int head[maxn], tot;
void addE(int u,int v) {
e[tot].to=v;
e[tot].ne=head[u];
head[u]=tot++;
} int fa[maxn], son[maxn], dep[maxn], num[maxn];
int top[maxn], p[maxn], fp[maxn], pos; void init() {
tot=; mem(head,);
pos=; mem(son,);
} struct TREE {
int l,r; // 区间左右位置
int Lw,Rw; // 左端点的值 右端点的值
int LL,LR;
// 以左端点始的下降LCIS长度 以左端点始的上升LCIS长度
int RL,RR;
// 以右端点始的下降LCIS长度 以右端点始的上升LCIS长度
int Len,Ren;
// 该区间的 从左上升LCIS长度 从右上升LCIS长度
TREE(){ l=r=Lw=Rw=LL=LR=RL=RR=Len=Ren=; }
}tree[maxn<<]; // --------------------以下是线段树------------------------- TREE Merge(TREE L,TREE R) {
if(R.Len==) return L;
TREE ans=L;
ans.r=R.r, ans.Rw=R.Rw;
ans.Len=max(L.Len,R.Len);
ans.Ren=max(L.Ren,R.Ren);
if(L.LL==L.r-L.l+ && L.Rw>R.Lw) ans.LL=L.LL+R.LL;
else ans.LL=L.LL;
if(L.LR==L.r-L.l+ && L.Rw<R.Lw) ans.LR=L.LR+R.LR;
else ans.LR=L.LR;
if(R.RL==R.r-R.l+ && L.Rw<R.Lw) ans.RL=R.RL+L.RL;
else ans.RL=R.RL;
if(R.RR==R.r-R.l+ && L.Rw>R.Lw) ans.RR=R.RR+L.RR;
else ans.RR=R.RR;
ans.Len=max(ans.Len,ans.LR);
ans.Len=max(ans.Len,ans.RL);
ans.Ren=max(ans.Ren,ans.LL);
ans.Ren=max(ans.Ren,ans.RR);
if(L.Rw<R.Lw) ans.Len=max(ans.Len,L.RL+R.LR);
if(L.Rw>R.Lw) ans.Ren=max(ans.Ren,L.RR+R.LL);
return ans;
}
void build(int l,int r,int rt) {
tree[rt].l=l, tree[rt].r=r;
if(l==r) {
tree[rt].LL=tree[rt].LR=,
tree[rt].RL=tree[rt].RR=,
tree[rt].Len=tree[rt].Ren=;
tree[rt].Lw=tree[rt].Rw=fp[l];
return;
}
int m=(l+r)>>;
build(lson), build(rson);
tree[rt]=Merge(tree[rt<<],tree[rt<<|]);
}
TREE query(int L,int R,int l,int r,int rt) {
if(L==l && r==R) return tree[rt];
int m=(l+r)>>;
if(R<=m) return query(L,R,lson);
else if(L>m) return query(L,R,rson);
else return Merge(query(L,m,lson),query(m+,R,rson));
} // --------------------以上是线段树------------------------- // --------------------以下是树链剖分------------------------- void dfs1(int u,int pre,int d) {
dep[u]=d; fa[u]=pre; num[u]=;
for(int i=head[u];i;i=e[i].ne) {
int v=e[i].to;
if(v!=fa[u]) {
dfs1(v,u,d+);
num[u]+=num[v];
if(!son[u] || num[v]>num[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int sp) {
top[u]=sp; p[u]=++pos; fp[p[u]]=w[u];
if(!son[u]) return;
dfs2(son[u],sp);
for(int i=head[u];i;i=e[i].ne) {
int v=e[i].to;
if(v!=son[u] && v!=fa[u])
dfs2(v,v);
}
}
int solve(int x,int y) {
int fx=top[x], fy=top[y];
TREE ans1, ans2;
bool flag=;
while(fx!=fy) {
if(dep[fx]>dep[fy]) {
ans1=Merge(query(p[fx],p[x],root),ans1);
x=fa[fx];
} else {
ans2=Merge(query(p[fy],p[y],root),ans2);
y=fa[fy];
}
fx=top[x], fy=top[y];
}
if(p[x]>p[y]) ans1=Merge(query(p[y],p[x],root),ans1);
else ans2=Merge(query(p[x],p[y],root),ans2);
int ans=max(ans1.Ren,ans2.Len);
if(ans1.Lw<ans2.Lw) ans=max(ans,ans1.LL+ans2.LR);
return ans;
} // --------------------以上是树链剖分------------------------- void initQTree() {
dfs1(,,), dfs2(,);
build(root);
}
}T; int main()
{
int t, tcase=;
scanf("%d",&t);
bool st=;
while(t--) {
if(st) puts("");
scanf("%d",&n);
T.init();
for(int i=;i<=n;i++) scanf("%d",&w[i]);
for(int i=;i<=n;i++) {
int v; scanf("%d",&v);
T.addE(i,v); T.addE(v,i);
}
T.initQTree();
scanf("%d",&q);
printf("Case #%d:\n",tcase++);
while(q--) {
int u,v; scanf("%d%d",&u,&v);
printf("%d\n",T.solve(u,v));
} st=;
} return ;
}

POJ 4718 /// 树链剖分+线段树区间合并 求树上两点间的LCIS长度的更多相关文章

  1. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  2. 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并

    题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  7. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

  9. B20J_2243_[SDOI2011]染色_树链剖分+线段树

    B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...

随机推荐

  1. HTTP六大请求

    标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD 6.Options 但其实我们大部分情况下只用到了GET和POST.如果想设计一个符合RE ...

  2. 戏说 .NET GDI+系列学习教程(三、Graphics类的方法的总结)

  3. web自动化selenium click()方法失效的解决办法

    使用Python写web-ui自动化脚本时,如果浏览器窗口比较小或者电脑屏幕比较小时, 可能会遇到页面元素的点击click()方法失效的问题,报错如下: Element <span>... ...

  4. SaaS,PaaS,IaaS都是什么鬼?

    IaaS Infrastructure as a Service,基础设施即服务. 假如你现在要做一个网站,你肯定要有一台服务器或者虚拟机,要么自己搭建,要么买服务器运营商的.说白了,IaaS就是解决 ...

  5. leetcode.字符串.5最长回文子串-Java

    1. 具体题目 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" ...

  6. 判断IE版本与各浏览器的语句

    ---恢复内容开始--- 一.IE下判断IE版本的语句 <!--[if lte IE 6]> <![endif]--> IE6及其以下版本可见    <!--[if lt ...

  7. springboot + zipkin + mysql

    zipkin的数据存储可以存在4个地方: 内存(仅用于测试,数据不会持久化,zipkin-server关掉,数据就没有了) 这也是之前使用的 mysql 可能是最熟悉的方式 es Cassandra ...

  8. 2019-5-16-WPF-光标初始化的时候-temp-文件夹满了无法创建

    title author date CreateTime categories WPF 光标初始化的时候 temp 文件夹满了无法创建 lindexi 2019-05-16 19:16:27 +080 ...

  9. 基于nginx+tomcat部署商城系统并连接数据库

    需三台服务器nginx 192.168.200.111tomcat 192.168.200.112tomcat 192.168.200.113 192.168.200.111[root@localho ...

  10. Windows server 2016 / Windows 10关于域管理员帐号权限不足的问题

    今天在测试windows server 2016的域创建时,当安装结束之后,发现使用Administrator用户进行操作时,被提示了权限不足这个问题.于是我在百度上查找了一番之后,找到了解决方法. ...