【BZOJ5469】[FJOI2018]领导集团问题(动态规划,线段树合并)
【BZOJ5469】[FJOI2018]领导集团问题(动态规划,线段树合并)
题面
题解
题目就是让你在树上找一个最大的点集,使得两个点如果存在祖先关系,那么就要满足祖先的权值要小于等于儿子的权值。
首先离散权值。
考虑一个暴力\(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]领导集团问题(动态规划,线段树合并)的更多相关文章
- 洛谷P4577 [FJOI2018]领导集团问题(dp 线段树合并)
题意 题目链接 Sol 首先不难想到一个dp,设\(f[i][j]\)表示\(i\)的子树内选择的最小值至少为\(j\)的最大个数 转移的时候维护一个后缀\(mx\)然后直接加 因为后缀max是单调不 ...
- BZOJ 5469: [FJOI2018]领导集团问题 dp+线段树合并
在 dp 问题中,如果发现可以用后缀最大值来进行转移的话可以考虑去查分这个后缀最大值. 这样的话可以用差分的方式来方便地进行维护 ~ #include <bits/stdc++.h> #d ...
- bzoj5469 [FJOI2018]领导集团问题
题目描述: bz luogu 题解: 相当于树上$LIS$问题. 考虑一维情况下的贪心,我们可以用multiset启发式合并搞. 代码: #include<set> #include< ...
- [FJOI2018]领导集团问题
[FJOI2018]领导集团问题 dp[i][j],i为根子树,最上面的值是j,选择的最大值 观察dp方程 1.整体Dp已经可以做了. 2.考虑优美一些的做法: dp[i]如果对j取后缀最大值,显然是 ...
- 题解-FJOI2018 领导集团问题
题面 FJOI2018 领导集团问题 给一棵树 \(T(|T|=n)\),每个点有个权值 \(w_i\),从中选出一个子点集 \(P=\{x\in {\rm node}|x\in T\}\),使得 \ ...
- 「题解报告」P4577 [FJOI2018]领导集团问题
题解 P4577 [FJOI2018]领导集团问题 题解区好像没有线段树上又套了二分的做法,于是就有了这片题解. 题目传送门 怀着必 WA 的决心交了两发,一不小心就过了. 题意 求一个树上最长不下降 ...
- P4577 [FJOI2018]领导集团问题
P4577 [FJOI2018]领导集团问题 我们对整棵树进行dfs遍历,并用一个multiset维护对于每个点,它的子树可取的最大点集. 我们遍历到点$u$时: 不选点$u$,显然答案就为它的所有子 ...
- 5469: [FJOI2018]领导集团问题
5469: [FJOI2018]领导集团问题 链接 题意: 要求在一棵树内选一个子集,满足子集内的任意两个点u,v,如果u是v的祖先,那么u的权值小于等于v. 分析: dp[u][i]表示在u的子树内 ...
- BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树
BZOJ_1672_[Usaco2005 Dec]Cleaning Shifts 清理牛棚_动态规划+线段树 题意: 约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群 ...
随机推荐
- 【转】redis-cluster安装配置
需要三台虚拟机(生产环境是3个物理机),分配静态IP.cluster中共6个节点.3主3从.本文中每个虚拟机上的redis端口:6379 6380. 需要注意的两点: 3个主节点分别位于3台虚拟机上, ...
- 【学习总结】C-翁恺老师-入门-第0周<程序设计与C>
[学习总结]C-翁恺老师-入门-总 1-首先按视频说的下载编辑器 <DevC++> 并一路默认设置: 安装包下载链接 (我有vc6.0不过预感告诉我老师要用类似CS50里那种命令行编辑器? ...
- centos 7 aufs
Docker storage drivers | Docker Documentationhttps://docs.docker.com/storage/storagedriver/select-st ...
- 五、es6 Set
一.特点 1.是一个构造函数 2.类数组,元素唯一.没有重复 二.new Set(); 二.构造函数接受数组将数组转换成Set数据结构,[...new Set(1,3)],转化成对象: console ...
- C#复习笔记(4)--C#3:革新写代码的方式(扩展方法)
扩展方法 扩展方法有以下几个需求: 你想为一个类型添加一些 成员: 你不需要为类型的实例添加任何更多的数据: 你不能改变类型本身, 因为是别人的代码. 对于C#1和C#2中的静态方法,扩展方法是一种更 ...
- linux 安装 SVN server
安装 使用yum安装非常简单: yum install subversion 配置 2.1. 创建仓库 我们这里在/home下建立一个名为svn的仓库(repository),以后所有代码都放在这个下 ...
- Mysql 5.7 Windows 版本(zip)的安装简单过程
1. 下载zip包 https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.25-winx64.zip 2. 找一个目录解压缩 3. 简单进行安装: ...
- 网络编程--使用UDP发送接收数据
package com.zhangxueliang.udp; import java.io.IOException; import java.net.DatagramPacket; import ja ...
- python爬虫之pandas
一.简介: Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模 ...
- SOAP-ERROR: Encoding: string … is not a valid utf-8 string
今天遇到一个错误,看标题就知道是什么错误了.... 最坑爹的是,不是所有的用户会报这个错误.只有少部分.在生产环境又没办法调试. 找了半天都不知道什么原因,字面意思大概是需要一个utf8编码的字符串, ...