BZOJ 4919 [Lydsy1706月赛]大根堆 (SRM08 T3)
2024-08-27 16:53:33
【题解】
求一个序列的LIS有一个二分做法是这样的:f[i]表示长度为i的上升序列中最后一个数最小可以是多少,每次二分大于等于当前数字x的f[j],把f[j]修改为x;如果找不到这样的f[j],那就把长度加一并记录新的f(即f[++len]=x)
现在我们把这个做法放到树上,同样是可以做的。我们用set维护子树内的f数组,父节点在其孩子合并得到的set中二分第一个大于等于它的数字,换成父节点自己的值。合并子树的set直接启发式合并即可。两个log的复杂度。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define N 200010
#define rg register
#define LL long long
using namespace std;
int n,tot,last[N],val[N];
multiset<int>f[N];
struct edge{
int to,pre;
}e[N];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
void dfs(int x,int fa){
for(rg int i=last[x],to;i;i=e[i].pre){
dfs(to=e[i].to,x);
if(f[to].size()>f[x].size()) swap(f[x],f[to]);
for(set<int>::iterator j=f[to].begin();j!=f[to].end();j++) f[x].insert(*j);
f[to].clear();
}
if(f[x].size()>&&f[x].lower_bound(val[x])!=f[x].end()) f[x].erase(f[x].lower_bound(val[x]));
f[x].insert(val[x]);
}
int main(){
n=read();
for(rg int i=;i<=n;i++){
val[i]=read(); int fa=read();
e[++tot]=(edge){i,last[fa]}; last[fa]=tot;
}
dfs(,);
printf("%d\n",f[].size());
return ;
}
最新文章
- Denormalization
- 2>;&;1 linux
- linq join的lambda写法
- [MKRCVCD]Burning SDK report AddFile error
- EXCEL快速自动填充方法集锦
- 关于在windows上的wamp集成环境和xampp上安装mongo扩展
- stl 比较和boost LessThanComparable
- Filter过滤器简单应用( 接口访问控制 )
- Linux-以指定用户运行redis
- CSS的IE6、IE7、FF兼容性写法
- 防DDOS攻击
- [zz]pg_hba.conf 一种安全地配置策略
- vector(相对线程安全) arryList(线程不安全)
- 布隆过滤器(Bloom Filter)的原理和实现
- C# richTextBox封装的一个打印的类
- POJ3690 Constellations 【KMP】
- 运维老鸟教你安装centos6.5如何选择安装包
- 8. 使用ueditor添加文章
- RESTful-5开发API
- asp.net core mvc发布后显示异常错误信息的方法
热门文章
- python-----tuple用法
- 你想知道的关于JavaScript作用域的一切
- java编程中的断言工具类(org.springframework.util.Assert)
- [Swift通天遁地]一、超级工具-(17)自定义的CVCalendar日历
- Juicer.js模板引擎问题
- Java多线程(八) synchronized 抛出异常锁自动解除
- C#中接受一个非字符串的输入
- Docker学习系列(二):Docker三十分钟快速入门(上)
- Paxos,Raft,Zab一致性协议-Raft篇
- [ CodeForces 1063 B ] Labyrinth