树上最长不下降链 线段树合并+set
读错题了,然后写了一个树上 LIS,应该是对的吧......
code:
#include <bits/stdc++.h>
#define N 200005
#define LL long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
struct seg
{
#define lson t[x].ls
#define rson t[x].rs
int tot;
struct node
{
int ls,rs,maxx;
}t[N*50];
int newnode() { return ++tot; }
void update(int &x,int l,int r,int p,int v)
{
if(!x) x=newnode();
t[x].maxx=max(t[x].maxx,v);
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) update(lson,l,mid,p,v);
else update(rson,mid+1,r,p,v);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
int now=newnode();
t[now].maxx=max(t[x].maxx,t[y].maxx);
t[now].ls=merge(t[x].ls,t[y].ls);
t[now].rs=merge(t[x].rs,t[y].rs);
return now;
}
int query(int x,int l,int r,int L,int R)
{
if(!x) return 0;
if(l>=L&&r<=R) return t[x].maxx;
int mid=(l+r)>>1,re=0;
if(L<=mid) re=max(re, query(lson,l,mid,L,R));
if(R>mid) re=max(re, query(rson,mid+1,r,L,R));
return re;
}
#undef lson
#undef rson
}in,de;
multiset<int>s1,s2;
multiset<int>::iterator it1,it2;
int n,edges;
int rt_in[N],rt_de[N],val[N],ans[N],A[N],hd[N],to[N<<1],nex[N<<1],max1[N],max2[N];
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs(int u,int ff)
{
int max_in=1,max_de=1;
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==ff) continue;
dfs(v,u);
max_in=max(max_in, in.query(rt_in[v],1,n,val[u],n)+1);
max_de=max(max_de, de.query(rt_de[v],1,n,1,val[u])+1);
}
int tl=0;
s1.clear();
s2.clear();
for(int i=hd[u];i;i=nex[i])
{
int v=to[i];
if(v==ff) continue;
max1[++tl]=in.query(rt_in[v],1,n,val[u],n);
max2[tl]=de.query(rt_de[v],1,n,1,val[u]);
s1.insert(max1[tl]);
s2.insert(max2[tl]);
}
if(tl>1)
{
for(int i=1;i<=tl;++i)
{
s1.erase(s1.lower_bound(max1[i]));
s2.erase(s2.lower_bound(max2[i]));
it1=s1.end(), it2=s2.end();
it1--,it2--;
ans[u]=max(ans[u], max2[i]+(*it1)+1);
ans[u]=max(ans[u], max1[i]+(*it2)+1);
s1.insert(max1[i]);
s2.insert(max2[i]);
}
}
ans[u]=max(ans[u],max(max_in,max_de));
in.update(rt_in[u],1,n,val[u],max_in);
de.update(rt_de[u],1,n,val[u],max_de);
if(ff)
{
rt_in[ff]=in.merge(rt_in[ff],rt_in[u]);
rt_de[ff]=de.merge(rt_de[ff],rt_de[u]);
}
}
int main()
{
// setIO("input");
int i,j;
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%d",&val[i]), A[i]=val[i];
sort(A+1,A+1+n);
for(i=1;i<=n;++i) val[i]=lower_bound(A+1,A+1+n,val[i])-A;
for(i=2;i<=n;++i)
{
int x;
scanf("%d",&x);
add(x,i),add(i,x);
}
dfs(1,0);
int tmp=0;
for(i=1;i<=n;++i) tmp=max(tmp,ans[i]);
printf("%d\n",tmp);
return 0;
}
树上最长不下降链 线段树合并+set的更多相关文章
- 最长不下降子序列(线段树优化dp)
最长不下降子序列 题目大意: 给定一个长度为 N 的整数序列:A\(_{1}\),A\(_{2}\),⋅⋅⋅,A\(_{N}\). 现在你有一次机会,将其中连续的 K 个数修改成任意一个相同值. 请你 ...
- [Vani有约会]雨天的尾巴——树上差分+动态开点线段树合并
题目描述 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮. 然后深绘里想知道,当所 ...
- 2018.08.28 洛谷P4556 [Vani有约会]雨天的尾巴(树上差分+线段树合并)
传送门 要求维护每个点上出现次数最多的颜色. 对于每次修改,我们用树上差分的思想,然后线段树合并统计答案就行了. 注意颜色很大需要离散化. 代码: #include<bits/stdc++.h& ...
- CF 666E Forensic Examination 【SAM 倍增 线段树合并】
CF 666E Forensic Examination 题意: 给出一个串\(s\)和\(n\)个串\(t_i\),\(q\)次询问,每次询问串\(s\)的子串\(s[p_l:p_r]\)在串\(t ...
- 有趣的线段树模板合集(线段树,最短/长路,单调栈,线段树合并,线段树分裂,树上差分,Tarjan-LCA,势能线段树,李超线段树)
线段树分裂 以某个键值为中点将线段树分裂成左右两部分,应该类似Treap的分裂吧(我菜不会Treap).一般应用于区间排序. 方法很简单,就是把分裂之后的两棵树的重复的\(\log\)个节点新建出来, ...
- BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)
BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...
- 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree
原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...
- [BJWC2018]Border 的四种求法(后缀自动机+链分治+线段树合并)
题目描述 给一个小写字母字符串 S ,q 次询问每次给出 l,r ,求 s[l..r] 的 Border . Border: 对于给定的串 s ,最大的 i 使得 s[1..i] = s[|s|-i+ ...
- 【洛谷4482】Border的四种求法(后缀自动机_线段树合并_链分治)
这题我写了一天后交了一发就过了我好兴奋啊啊啊啊啊啊 题目 洛谷 4482 分析 这题明明可以在线做的,为什么我见到的所有题解都是离线啊 -- 什么时候有机会出一个在线版本坑人. 题目的要求可以转化为求 ...
随机推荐
- Python之路【第九篇】:Python面向对象
阅读目录 一.三大编程范式 编程范式即编程的方法论,标识一种编程风格: 大家学习了基本的python语法后,大家可以写python代码了,然后每个人写代码的风格不同,这些不同的风格就代表了不同的流派: ...
- Python使用队列实现Josephus问题
Josephus问题,在这个古老的问题中,N个深陷绝境的人一致同意通过以下方式减少生存的人数.他们围坐一圈(位置记为0~N-1)并从第一个人报数,报到M的人会被杀死, 知道最后一个人留下来.传说中Jo ...
- 备份和还原 第三篇:master 数据库的备份和还原
在SQL Server 中,master 数据库记录系统级别的元数据,例如,logon accounts, endpoints, linked servers, and system configur ...
- Java 阿拉伯数字转换为中文大写数字
Java 阿拉伯数字转换为中文大写数字 /** * <html> * <body> * <P> Copyright 1994 JsonInternational&l ...
- 过滤器 & 监听器 & 拦截器
过滤器: https://blog.csdn.net/MissEel/article/details/79351231 https://blog.csdn.net/qq_32363305/articl ...
- Python进阶----数据库的基础,关系型数据库与非关系型数据库(No SQL:not only sql),mysql数据库语言基础(增删改查,权限设定)
day37 一丶Python进阶----数据库的基础,mysql数据库语言基础(增删改查,权限设定) 什么是数据库: 简称:DataBase ---->DB 数据库即存放数据的仓库, ...
- .net core 使用swagger接口描述
首先安装nuget包 Swashbuckle.AspNetCore.Swagger Swashbuckle.AspNetCore.SwaggerGen Swashbuckle.AspNetCore.S ...
- 三星手机使用应用沙盒一键修改路由mac数据
之前文章介绍了怎么在安卓手机上安装激活xposed框架,xposed框架的极强的功能大家都知道,能够不修改apk的前提下,修改系统底层的参数,打比方在某些应用情景,大家需要修改手机的某个系统参数,这情 ...
- CentOS 7 使用 firewalld 打开关闭防火墙与端口
1.firewalld的基本使用启动: systemctl start firewalld关闭: systemctl stop firewalld查看状态: systemctl status fire ...
- JavaScript: 详解正则表达式之一
正则表达式是一个精巧的利器,经常用来在字符串中查找和替换,JavaScript语言参照Perl,也提供了正则表达式相关模块,开发当中非常实用,在一些类库或是框架中,比如jQuery,就存在大量的正则表 ...