BZOJ 4919: [Lydsy1706月赛]大根堆
F[x][i]表示x的子树中取的数字<=i的最大值,线段树合并优化DP
写得很难看,并不知道好看的写法
#include<cstdio>
#include<algorithm>
using namespace std;
int cnt,n,Num,ans,last[200005],tag[10000005],ls[10000005],rs[13000005],E[200005],a[200005],Fa[200005],root[200005],ANS[200005],tree[10000005];
struct node{
int to,next;
}e[1000005];
void add(int a,int b){
e[++cnt].to=b;
e[cnt].next=last[a];
last[a]=cnt;
}
void push_down(int x){
if (ls[x]) tag[ls[x]]+=tag[x],tree[ls[x]]+=tag[x],tree[ls[x]]=max(tree[ls[x]],tree[x]);
if (rs[x]) tag[rs[x]]+=tag[x],tree[rs[x]]+=tag[x],tree[rs[x]]=max(tree[rs[x]],tree[x]);
tag[x]=0;
}
int merge(int x,int y){
if (!x) return y;
if (!y) return x;
push_down(x); push_down(y);
if (!ls[x]) ls[x]=ls[y],tree[ls[x]]+=tree[x],tag[ls[x]]+=tree[x];
else if (!ls[y]) tree[ls[x]]+=tree[y],tag[ls[x]]+=tree[y];
else ls[x]=merge(ls[x],ls[y]);
if (!rs[x]) rs[x]=rs[y],tree[rs[x]]+=tree[x],tag[rs[x]]+=tree[x];
else if (!rs[y]) tree[rs[x]]+=tree[y],tag[rs[x]]+=tree[y];
else rs[x]=merge(rs[x],rs[y]);
tree[x]+=tree[y];
return x;
}
int query(int t,int l,int r,int x){
if (!t) return 0;
if (l==r) return tree[t];
push_down(t);
int mid=(l+r)>>1;
if (x<=mid) return max(tree[t],query(ls[t],l,mid,x));
else return max(tree[t],query(rs[t],mid+1,r,x));
}
void insert(int &t,int l,int r,int x,int y,int Val){
if (l>y || r<x) return;
if (!t) t=++cnt;
if (l>=x && r<=y){
tree[t]=max(tree[t],Val);
return;
}
push_down(t);
int mid=(l+r)>>1;
insert(ls[t],l,mid,x,y,Val);
insert(rs[t],mid+1,r,x,y,Val);
}
void solve(int x){
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
solve(V);
root[x]=merge(root[x],root[V]);
}
int Key=query(root[x],1,Num,a[x]-1);
insert(root[x],1,Num,a[x],Num,Key+1);
}
int main(){
scanf("%d",&n);
for (int i=1; i<=n; i++) {
scanf("%d%d",&a[i],&Fa[i]);
if (Fa[i]) add(Fa[i],i);
}
E[++n]=-1e9;
for (int i=1; i<=n; i++) E[i]=a[i];
sort(E+1,E+n+1);
Num=unique(E+1,E+n+1)-E-1;
for (int i=1; i<=n; i++) a[i]=lower_bound(E+1,E+Num+1,a[i])-E;
cnt=0;
solve(1);
for (int i=1; i<=Num; i++) ANS[i]=query(root[1],1,Num,i);
int ans=0;
for (int i=1; i<=Num; i++) ans=max(ans,ANS[i]);
printf("%d\n",ans);
return 0;
}
BZOJ 4919: [Lydsy1706月赛]大根堆的更多相关文章
- bzoj 4919 [Lydsy1706月赛]大根堆 set启发式合并+LIS
4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 599 Solved: 260[Submit][Stat ...
- BZOJ 4919: [Lydsy1706月赛]大根堆 set启发式合并
这个和 bzoj 5469 几乎是同一道题,但是这里给出另一种做法. 你发现你要求的是一个树上 LIS,而序列上的 LIS 有一个特别神奇的 $O(n\log n) $ 做法. 就是维护一个单调递增的 ...
- 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],那就把 ...
- [Lydsy1706月赛]大根堆
4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 358 Solved: 150[Submit][Stat ...
- bzoj4919 [Lydsy1706月赛]大根堆
Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质: ...
- BZOJ4919:[Lydsy1706月赛]大根堆(set启发式合并)
Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质: ...
- BZOJ4919[Lydsy1706月赛]大根堆-------------线段树进阶
是不是每做道线段树进阶都要写个题解..根本不会写 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...
随机推荐
- 架构演进历程及为什么选择Spring Cloud
单体式架构: 垂直拆分: 垂直拆分的特点: 分布式服务: 分布式服务的特点: SOA面向服务的架构: 服务治理: 微服务: 微服务结构: 服务调用方式: http客户端工具:
- keil下JLINK在线调试仿真设置,SWD连接
keil下JLINK在线调试仿真设置,以下三个步骤搞定: 有时我们编译时会遇到空间不足的情况,首先我们应该把 flash和RAM的size 设置为当前所用芯片的大小,如下我使用了一个片上flash 2 ...
- uvm_reg_predictor——寄存器模型(十七)
这是寄存器模型类中唯一派生自uvm_component的类,我们的寄存器模式需要实时,以最接近的方式知道DUT中寄存器的变化,uvm_reg_predictor就是为这个而生的. // TITLE: ...
- 干货|java缓存技术详解
一.缓存是什么? 请点击此处输入图片描述 Cache ①高速缓冲存储器,其中复制了频繁使用的数据以利于快速访问. ②位于速度相差较大的两种硬件/软件之间,用于协调两者数据传输速度差异的结构 二.缓存有 ...
- Python+selenium之下载文件
一.Firefox文件下载 Web容许我们设置默认的文件下载路劲,文件会自动下载并且存放在指定的目录下. from selenium import webdriver import os fp = w ...
- 网站安全webshell扫描
做个记录,使用Detector进行php网站webshell扫描 开源项目托管地址:https://github.com/emposha/PHP-Shell-Detector安装使用都很简单
- python基础教程总结5——函数
1.函数创建 1).函数代码块以def关键词开头,后接函数标识符名称和圆括号()2).任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数3).函数的第一行语句可以选择性地使用文档字符串 ...
- Codeforces Round #319 (Div. 2) B Modulo Sum (dp,鸽巢)
直接O(n*m)的dp也可以直接跑过. 因为上最多跑到m就终止了,因为前缀sum[i]取余数,i = 0,1,2,3...,m,有m+1个余数,m的余数只有m种必然有两个相同. #include< ...
- halt, reboot, poweroff - 中止系统运行
SYNOPSIS /sbin/halt [-n] [-w] [-d] [-f] [-i] [-p] /sbin/reboot [-n] [-w] [-d] [-f] [-i] /sbin/powero ...
- JS实现2,8,10,16进制的相互转换
// 10进制转为16进制 var a=1234567890; console.log(a.toString(16)) //499602d2 // 16进制转为10进制 var num=parseIn ...