【BZOJ5469】[FJOI2018]领导集团问题(动态规划,线段树合并)

题面

BZOJ

洛谷

题解

题目就是让你在树上找一个最大的点集,使得两个点如果存在祖先关系,那么就要满足祖先的权值要小于等于儿子的权值。

首先离散权值。

考虑一个暴力\(dp\),设\(f[i][j]\)表示以\(i\)为根,子树中被选择的最小值为\(j\)时能够被选出的最大点树。然后xjb转移一下就写出了一个\(O(n^3)\)的优秀做法。

然后把状态从恰好变成至少,然后就得到了一个\(O(n^2)\)的做法。

考虑\(O(n^2)\)的\(dp\),本质上就是在维护一个后缀的最大值。

不难发现后缀最大值一定是不降的。

考虑对于后缀进行差分,每次相当于现在\(w[i]\)位置加一,然后往前更新一段,直到下一个差分数组上有\(1\)的位置。

那么用线段树合并就可以解决这个问题,给\(w[i]\)位置加一,然后线段树上二分找到上一个为\(1\)的位置然后把它减一就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 200200
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int n,ans,w[MAX],S[MAX],tot,rt[MAX];
int ls[MAX*18],rs[MAX*18],t[MAX*18],node;
void Modify(int &x,int l,int r,int p)
{
if(!x)x=++node;t[x]+=1;if(l==r)return;
int mid=(l+r)>>1;
if(p<=mid)Modify(ls[x],l,mid,p);
else Modify(rs[x],mid+1,r,p);
}
bool Flag;
void Calc(int x)
{
if(!x)return;t[x]-=1;
if(t[rs[x]])Calc(rs[x]);
else Calc(ls[x]);
}
void Minus(int x,int l,int r,int p)
{
if(l==r)return;int mid=(l+r)>>1;
if(p<=mid)Minus(ls[x],l,mid,p);
else
{
Minus(rs[x],mid+1,r,p);
if(!Flag&&t[ls[x]])Flag=true,Calc(ls[x]);
}
if(Flag)t[x]-=1;
}
void Merge(int &x,int &y)
{
if(!x||!y){x|=y;return;}t[x]+=t[y];
Merge(ls[x],ls[y]);Merge(rs[x],rs[y]);
}
void dfs(int u)
{
for(int i=h[u];i;i=e[i].next)
dfs(e[i].v),Merge(rt[u],rt[e[i].v]);
Modify(rt[u],1,tot,w[u]);
Flag=false;Minus(rt[u],1,tot,w[u]);
}
int main()
{
n=read();
for(int i=1;i<=n;++i)S[++tot]=w[i]=read();
for(int i=2;i<=n;++i)Add(read(),i);
S[++tot]=1e9+1;sort(&S[1],&S[tot+1]);tot=unique(&S[1],&S[tot+1])-S-1;
for(int i=1;i<=n;++i)w[i]=lower_bound(&S[1],&S[tot+1],w[i])-S;
dfs(1);printf("%d\n",t[rt[1]]);
return 0;
}

【BZOJ5469】[FJOI2018]领导集团问题(动态规划,线段树合并)的更多相关文章

  1. 洛谷P4577 [FJOI2018]领导集团问题(dp 线段树合并)

    题意 题目链接 Sol 首先不难想到一个dp,设\(f[i][j]\)表示\(i\)的子树内选择的最小值至少为\(j\)的最大个数 转移的时候维护一个后缀\(mx\)然后直接加 因为后缀max是单调不 ...

  2. BZOJ 5469: [FJOI2018]领导集团问题 dp+线段树合并

    在 dp 问题中,如果发现可以用后缀最大值来进行转移的话可以考虑去查分这个后缀最大值. 这样的话可以用差分的方式来方便地进行维护 ~ #include <bits/stdc++.h> #d ...

  3. bzoj5469 [FJOI2018]领导集团问题

    题目描述: bz luogu 题解: 相当于树上$LIS$问题. 考虑一维情况下的贪心,我们可以用multiset启发式合并搞. 代码: #include<set> #include< ...

  4. [FJOI2018]领导集团问题

    [FJOI2018]领导集团问题 dp[i][j],i为根子树,最上面的值是j,选择的最大值 观察dp方程 1.整体Dp已经可以做了. 2.考虑优美一些的做法: dp[i]如果对j取后缀最大值,显然是 ...

  5. 题解-FJOI2018 领导集团问题

    题面 FJOI2018 领导集团问题 给一棵树 \(T(|T|=n)\),每个点有个权值 \(w_i\),从中选出一个子点集 \(P=\{x\in {\rm node}|x\in T\}\),使得 \ ...

  6. 「题解报告」P4577 [FJOI2018]领导集团问题

    题解 P4577 [FJOI2018]领导集团问题 题解区好像没有线段树上又套了二分的做法,于是就有了这片题解. 题目传送门 怀着必 WA 的决心交了两发,一不小心就过了. 题意 求一个树上最长不下降 ...

  7. P4577 [FJOI2018]领导集团问题

    P4577 [FJOI2018]领导集团问题 我们对整棵树进行dfs遍历,并用一个multiset维护对于每个点,它的子树可取的最大点集. 我们遍历到点$u$时: 不选点$u$,显然答案就为它的所有子 ...

  8. 5469: [FJOI2018]领导集团问题

    5469: [FJOI2018]领导集团问题 链接 题意: 要求在一棵树内选一个子集,满足子集内的任意两个点u,v,如果u是v的祖先,那么u的权值小于等于v. 分析: dp[u][i]表示在u的子树内 ...

  9. BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树

    BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树 题意:  约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群 ...

随机推荐

  1. Python云端系统开发入门 pycharm代码

    html <!DOCTYPE html><html><head> <meta charset="UTF-8"> <title& ...

  2. 百度地图开发者API学习笔记一(转载)

    一,实现功能: 在地图上标记点,划线等操作.如下图. 2.代码: <!DOCTYPE html> <html> <head> <meta http-equiv ...

  3. Linux sed使用方法

    目录 sed处理流程 测试数据 sed命令格式 sed命令行格式 行定位 定位1行 定位区间行(多行) 定位某一行之外的行 定位有跨度的行 操作命令 -a (新增行) -i(插入行) -c(替代行) ...

  4. Linux下设置MySql自动启动

    https://www.cnblogs.com/sunny3096/p/7954146.html

  5. 关于百度地图API和jqGrid踩到的坑

    1.百度地图重新标记问题 var map = new BMap.Map("map"); ...... var marker = new BMap.Marker(point); // ...

  6. C\C++学习笔记 1

    C++记录1 C的头文件为math.h C++的为 cmath using编译指令 namespace 区分不同产品的函数.Mics::cout Linux::cout cout << 即 ...

  7. flex实现三栏等分布局

    前言 在实际开发中,我们经常会想要实现的一种布局方式就是三栏等分布局,那么我们如何来解决这个问题呢? 解决 方法一:flex 外层容器也就是ul设置display:flex,对项目也就是li设置fle ...

  8. MySQL 查询语句中自己定义的中文内容在Java Web 中显示为问号

    Java Web 端做查询时,性别字段存的是数字,1代表男,2代表女,取数据时将性别转为汉字显示在页面,sql语句如下,结果发生了问题  select a.emp_id,a.emp_name ,cas ...

  9. MongoDB操作(1)—MongoDB java驱动核心层次结构及操作流程

    MongoDB之java驱动学习 预备: 本地运行MongoDB采用默认端口20717: 安装MongoDB驱动: 以下关键步骤. 核心层次结构或步骤: 创建连接池:MongoClient实例. 对于 ...

  10. 转:Flutter Decoration背景设定(边框、圆角、阴影、形状、渐变、背景图像等)

    1 继续关系: BoxDecoration:实现边框.圆角.阴影.形状.渐变.背景图像 ShapeDecoration:实现四个边分别指定颜色和宽度.底部线.矩形边色.圆形边色.体育场(竖向椭圆).  ...