树上最长不下降链 线段树合并+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 分析 这题明明可以在线做的,为什么我见到的所有题解都是离线啊 -- 什么时候有机会出一个在线版本坑人. 题目的要求可以转化为求 ...
随机推荐
- 【爬坑笔记】c# 如何通过EF Core读写sql server的类似double型字段
=============================================== 2019/8/31_第1次修改 ccb_warlock == ...
- Etcd 使用入门
etcd简介 etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库.etcd内部采用raft协议作为一致性算法,etcd基于Go语 ...
- 女性对DeepNude脱衣技术的防护
写在前面的话 本文不提供下载方式,开源部分只是社区逆向后公开的部分源码 这篇文章有些人看了可能会比较极端,但不从技术角度分析又谈何防护?攻与防一直存在,不管是安全还是AI都是一样 你极端不极端,它就在 ...
- 1、C#多线程基础理论
系统为应用程序分配所需的内存以及其他资源,内存和资源的物理分离叫做进程. 进程是以线程为单位竞争CPU,那么什么是线程呢? 线程可看成一个可执行的指令单元,他使用进程中的数据,包含若干条指令,进程 ...
- codeforces Round #568(Div.2)A B C
有点菜,只写出了三道.活不多说,上题开干. A. Ropewalkers Polycarp decided to relax on his weekend and visited to the per ...
- Unicode 字符和UTF编码的理解
Unicode 编码的由来 我们都知道,计算机的内部全部是由二进制数字0, 1 组成的, 那么计算机就没有办法保存我们的文字, 这怎么行呢? 于是美国人就想了一个办法(计算机是由美国人发明的),也把文 ...
- java开发手册-总结与补充
1.分层领域模型规约 1.DO( Data Object):与数据库表结构一一对应,通过 DAO 层向上传输数据源对象. 2.DTO( Data Transfer Object):数据传输对象, Se ...
- Oracle 11g新特性direct path read引发的系统停运故障诊断处理
黎俊杰 | 2016-07-28 14:37 声明:部分表名为了脱敏而用XX代替 1.故障现象 (1)一个业务系统输入用户名与密码后无法进入首页,表现为一直在运行等待,运行缓慢 (2)整个系统无法正常 ...
- 我的oracle 健康检查报告
最近一直想用sql来生成oracle的健康检查报告,这样看起来一目了然,经过网上搜资料加自己整理终于算是成型了,部分结果如下图所示, 具体参考附件,恳请广大网友看看是否还有需要添加的地方. DB_he ...
- 给 linux redis 设置密码
在redis.conf 找到 下面添加一行: 这样的话,密码就可以设置成123456,然后重启redis就可以了.