BZOJ 4919: [Lydsy1706月赛]大根堆 set启发式合并
这个和 bzoj 5469 几乎是同一道题,但是这里给出另一种做法.
你发现你要求的是一个树上 LIS,而序列上的 LIS 有一个特别神奇的 $O(n\log n) $ 做法.
就是维护一个单调递增的栈,如果发现新加元素大于栈顶,则直接加入,否则在序列中二分出一个大于等于该元素的最小值,然后替换掉.
这个单调栈维护的并不是 LIS,而是 LIS 中每个长度的最小结尾数值.
这个拓展到树上同理,你发现儿子之间互不影响,所以可以直接合并.
然后,再用当前节点的值去替换一个大于等于这个值的最小值.
code:
#include <bits/stdc++.h>
#define N 200006
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,edges;
int hd[N],to[N<<1],nex[N<<1],id[N],A[N],val[N];
multiset<int>se[N];
multiset<int>::iterator it;
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void merge(int x,int y)
{
if(se[id[y]].size()>se[id[x]].size()) swap(id[x],id[y]);
for(it=se[id[y]].begin();it!=se[id[y]].end();it++) se[id[x]].insert(*it);
se[id[y]].clear();
}
void dfs(int u,int ff)
{
for(int i=hd[u];i;i=nex[i]) dfs(to[i],u), merge(u,to[i]);
it=se[id[u]].lower_bound(val[u]);
if(it!=se[id[u]].end()) se[id[u]].erase(it);
se[id[u]].insert(val[u]);
}
int main()
{
// setIO("input");
int i,j;
scanf("%d",&n);
for(i=1;i<=n;++i)
{
id[i]=i;
scanf("%d",&val[i]);
int ff;
scanf("%d",&ff);
if(ff) add(ff,i);
}
dfs(1,0);
printf("%d\n",se[id[1]].size());
return 0;
}
BZOJ 4919: [Lydsy1706月赛]大根堆 set启发式合并的更多相关文章
- bzoj 4919 [Lydsy1706月赛]大根堆 set启发式合并+LIS
4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 599 Solved: 260[Submit][Stat ...
- BZOJ.4919.[Lydsy1706月赛]大根堆(线段树合并/启发式合并)
题目链接 考虑树退化为链的情况,就是求一个最长(严格)上升子序列. 对于树,不同子树间是互不影响的.仿照序列上的LIS,对每个点x维护一个状态集合,即合并其子节点后的集合,然后用val[x]替换掉第一 ...
- BZOJ 4919: [Lydsy1706月赛]大根堆 启发式合并
我不会告诉你这是线段树合并的好题的... 好吧我们可以搞一个multiset在dfs时求出LIS(自带二分+排序)进行启发式合并,轻松加愉悦... #include<cstdio> #in ...
- BZOJ 4919 [Lydsy1706月赛]大根堆 (SRM08 T3)
[题解] 求一个序列的LIS有一个二分做法是这样的:f[i]表示长度为i的上升序列中最后一个数最小可以是多少,每次二分大于等于当前数字x的f[j],把f[j]修改为x:如果找不到这样的f[j],那就把 ...
- BZOJ4919:[Lydsy1706月赛]大根堆(set启发式合并)
Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质: ...
- BZOJ 4919: [Lydsy1706月赛]大根堆
F[x][i]表示x的子树中取的数字<=i的最大值,线段树合并优化DP 写得很难看,并不知道好看的写法 #include<cstdio> #include<algorithm& ...
- [Lydsy1706月赛]大根堆
4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 358 Solved: 150[Submit][Stat ...
- 【BZOJ4919】[Lydsy六月月赛]大根堆 线段树合并
[BZOJ4919][Lydsy六月月赛]大根堆 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...
- BZOJ4919 [Lydsy1706月赛]大根堆 【dp + 启发式合并】
题目链接 BZOJ4919 题解 链上的\(LIS\)维护一个数组\(f[i]\)表示长度为\(i\)的\(LIS\)最小的结尾大小 我们可以用\(multiset\)来维护这个数组,子树互不影响,启 ...
随机推荐
- Python之路【第十一篇】:Python面向对象之封装
一 引子 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把青菜,土豆,花菜,还有苹果一起装进麻袋,然后把麻袋封上口子.照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的. 在面向对象中这个麻袋就是 ...
- leetcode动态规划笔记二
动态规划 题目分类 一维dp 矩阵型DP Unique Paths II : 矩阵型DP,求所有方法总数 Minimum Path Sum:矩阵型,求最大最小值 Triangle : 矩阵型,求最大最 ...
- 用HTML、CSS、JS制作圆形进度条(无动画效果)
逻辑 1.首先有一个圆:蓝色的纯净的圆,效果: 2.再来两个半圆,左边一个,右边一个将此蓝色的圆盖住,效果: 此时将右半圆旋转60°,就会漏出底圆,效果: 然后我们再用一个比底圆小的圆去覆盖这个大 ...
- angular复习笔记4-模板
Angular复习笔记4-模板 简介 模板是一种自定义的标准化页面,通过模板和模板中的数据结合,可以生成各种各样的网页.在Angular中,模板的默认语言是HTML,几乎所有的HTML语法在模板中都是 ...
- python-pymysql防止sql注入攻击介绍
目录 pymysql sql 注入攻击 调用存储过程 pymysql pymysql 是一个第三方模块,帮我们封装了 建立表/用户认证/sql的执行/结果的获取 import pymysql # 步骤 ...
- mysql-表关系介绍(应用较多)
目录 表之间的关系(重点) foreign key (外键) 级联操作 (cascade) 两种级联操作 外键的使用 多对一(一对多) 多对多 一对一关系 表之间的关系(重点) foreign key ...
- 【转载】C#中List集合使用Clear方法清空集合
在C#中的List集合操作过程中,有时候需要清空List集合中的元素对象,将之重置为一个初始化的List集合对象,此时就可以使用到List集合的扩展方法Clear()方法,此方法将清空List集合中所 ...
- JAVA基础之HttpServletResponse响应
用户在客户端输入网址(虚拟路径)时,开始发送一个HTTP请求(请求行.请求头.请求体)至服务器.服务器内的Tomcat引擎会解析请求的地址,去找XML文件,然后根据虚拟路径找Servlet的真实路径, ...
- jemter csv参数化时注意问题
csv设置 请求参数中引用参数注意点: 查看结果树-请求-http:查看结果,乱码问题解决 1.需要设置下请求体编码 csv设置线程共享模式: 所有线程:测试计划中所有线程,假如说有线程1到线程n ( ...
- MySQL 5.7的复制架构,在有异步复制、半同步、增强半同步、MGR等的生产中,该如何选择?
一.生产环境中: 几种复制场景都有存在的价值.下面分别描述一下: 从成熟度上来选择,推荐:异步复制(GTID+ROW) 从数据安全及更高性能上选择:增强半同步 (在这个结构下也可以把innodb_fl ...