「题解报告」P4577 [FJOI2018]领导集团问题
题解 P4577 [FJOI2018]领导集团问题
题解区好像没有线段树上又套了二分的做法,于是就有了这片题解。
怀着必 WA 的决心交了两发,一不小心就过了。
题意
求一个树上最长不下降子序列。
思路
首先考虑裸的 dp:设 \(f_{u,j}\) 表示以 \(u\) 为根的子树里选的数的最大值不小于 \(j\) 能选多少个。
\begin{cases}
\sum_\limits{v\ is\ u's\ son}f_{v,j} &j>w_u\\
\max\{\sum_\limits{v\ is\ u's\ son}f_{v,j},\sum_\limits{v\ is\ u's\ son}f_{v,j+1}+1\} &j\le w_u
\end{cases}
\]
接下来是如何优化:
在 DFS 每个节点的过程中,用权值线段树维护 \(f_{u,j}\)。
首先把所有儿子的权值线段树和起来。
然后考虑在什么区间选上这个节点更优。
右端点肯定是 \(w_i\) ,那么我们二分求左端点,即二分一个最小的选了比不选更优的点。
单点查询用权值线段树,合并儿子们的树用线段树合并,区间修改用标记可持久化。
时间复杂度是 \(O(nlog^2n)\)。
虽然慢到起飞但是能过。
代码
#include<bits/stdc++.h>
#define _for(i,a,b) for(int i=a;i<=b;++i)
#define for_(i,a,b) for(int i=a;i>=b;--i)
#define ll long long
#define bdmd int mid=(l+r)>>1
using namespace std;
const int N=2e5+10,inf=0x3f3f3f3f;
int n,cnt,w[N];
vector<int>son[N];
inline int rnt(){
int x=0,w=1;char c=getchar();
while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*w;
}
namespace LISAN{
int ls[N];
void LiSan(){
_for(i,1,n){
ls[i]=w[i];
}
sort(ls+1,ls+n+1);
cnt=unique(ls+1,ls+n+1)-ls-1;
_for(i,1,n)
w[i]=lower_bound(ls+1,ls+cnt+1,w[i])-ls;
return;
}
}
class ValSegmentTree{
public:
int root[N],tot,uucnt,un_use[N*40];
class TREE{
public:
int left_son,right_son;
int val=0;
}tree[N*40];
const TREE NONE=(TREE){0,0,0};
#define ls(p) tree[p].left_son
#define rs(p) tree[p].right_son
#define l_s(p) tree[p].left_son,l,mid
#define r_s(p) tree[p].right_son,mid+1,r
#define va(p) tree[p].val
#define bdmd int mid=(l+r)>>1
inline int NewP(){
if(uucnt)
return un_use[uucnt--];
return ++tot;
}
inline void DeleteP(int p){
tree[p]=NONE;
un_use[++uucnt]=p;
return;
}
void UpdateQJ(int &p,int l,int r,int le,int ri,int val){
if(!p)p=NewP();
if(ri<l||r<le)return;
if(le<=l&&r<=ri)
va(p)+=val;
else{
bdmd;
UpdateQJ(l_s(p),le,ri,val);
UpdateQJ(r_s(p),le,ri,val);
}
}
int QueryP(int p,int l,int r,int x){
if(!p)return 0;
if(l==r)return va(p);
else{
bdmd;
if(x<=mid)
return va(p)+QueryP(l_s(p),x);
else
return va(p)+QueryP(r_s(p),x);
}
}
void Merge(int &p1,int p2){
if(!p1){p1=p2;return;}
if(!p2){return;}
va(p1)+=va(p2);
Merge(ls(p1),ls(p2));
Merge(rs(p1),rs(p2));
DeleteP(p2);
return;
}
#undef ls
#undef rs
#undef l_s
#undef r_s
#undef va
}tr;
void Dfs(int u,int father){
int sz=son[u].size();
_for(i,0,sz-1){
int v=son[u][i];
if(v==father)continue;
Dfs(v,u);
tr.Merge(tr.root[u],tr.root[v]);
}
int xuan=tr.QueryP(tr.root[u],1,cnt,w[u]+1)+1;
int l=1,r=w[u];
while(l<=r){
bdmd;
if(tr.QueryP(tr.root[u],1,cnt,mid)>=xuan)
l=mid+1;
else
r=mid-1;
}
tr.UpdateQJ(tr.root[u],1,cnt,l,w[u],1);
return;
}
int main(){
n=rnt();
_for(i,1,n)w[i]=rnt();
LISAN::LiSan();
_for(i,2,n){
int x=rnt();
son[i].push_back(x);
son[x].push_back(i);
}
Dfs(1,0);
printf("%d\n",tr.QueryP(tr.root[1],1,n,1));
return 0;
}
「题解报告」P4577 [FJOI2018]领导集团问题的更多相关文章
- P4577 [FJOI2018]领导集团问题
P4577 [FJOI2018]领导集团问题 我们对整棵树进行dfs遍历,并用一个multiset维护对于每个点,它的子树可取的最大点集. 我们遍历到点$u$时: 不选点$u$,显然答案就为它的所有子 ...
- 「题解报告」 P3167 [CQOI2014]通配符匹配
「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...
- 「题解报告」P2154 虔诚的墓主人
P2154 虔诚的墓主人 题解 原题传送门 题意 在 \(n\times m\) 一个方格上给你 \(w\) 个点,求方格里每个点正上下左右各选 \(k\) 个点的方案数. \(1 \le N, M ...
- 「题解报告」SP16185 Mining your own business
题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...
- 「题解报告」Blocks
P3503 Blocks 题解 原题传送门 思路 首先我们可以发现,若 \(a_l\) ~ \(a_r\) 的平均值大于等于 \(k\) ,则这个区间一定可以转化为都大于等于 \(k\) 的.我们就把 ...
- 「题解报告」P3354
P3354 题解 题目传送门 一道很恶心的树形dp 但是我喜欢 题目大意: 一片海旁边有一条树状的河,入海口有一个大伐木场,每条河的分叉处都有村庄.建了伐木场的村庄可以直接处理木料,否则要往下游的伐木 ...
- 「题解报告」CF1067A Array Without Local Maximums
大佬们的题解都太深奥了,直接把转移方程放出来让其他大佬们感性理解,蒟蒻们很难理解,所以我就写了一篇让像我一样的蒟蒻能看懂的题解 原题传送门 动态规划三部曲:确定状态,转移方程,初始状态和答案. --神 ...
- 洛谷P4577 [FJOI2018]领导集团问题(dp 线段树合并)
题意 题目链接 Sol 首先不难想到一个dp,设\(f[i][j]\)表示\(i\)的子树内选择的最小值至少为\(j\)的最大个数 转移的时候维护一个后缀\(mx\)然后直接加 因为后缀max是单调不 ...
- 「题解报告」P7301 【[USACO21JAN] Spaced Out S】
原题传送门 神奇的5分算法:直接输出样例. 20分算法 直接把每个点是否有牛的状态DFS一遍同时判断是否合法,时间复杂度约为\(O(2^{n^2})\)(因为有判断合法的剪枝所以会比这个低).而在前四 ...
随机推荐
- 自己实现一个自定义React项目脚手架「ReactCli」
前言 首先为什么想到自己实现一个React脚手架呢?是因为之前刚接触create-react-app时,觉得不太灵活.虽然文件目录很清晰,但是还是觉得不如VueCLI的可以自定义配置更加灵活.当然Re ...
- 分布式机器学习:同步并行SGD算法的实现与复杂度分析(PySpark)
1 分布式机器学习概述 大规模机器学习训练常面临计算量大.训练数据大(单机存不下).模型规模大的问题,对此分布式机器学习是一个很好的解决方案. 1)对于计算量大的问题,分布式多机并行运算可以基本解决. ...
- NFS网络文件系统搭建
1. 简介 NFS, 就是network file system的简称. 可以通过NFS, 来共享不同主机的文件.目录. 2010年,NFS已经发展到v4.1版本. 2. 应用场景 在中小型企业中,N ...
- UiPathExcel读取操作
一.Uipath操作Excel的相关基本概念 1.UiPath操作Excel的两组方法 App Integration > Excel VS System > File > W ...
- NC15052 求最值
NC15052 求最值 题目 题目描述 给你一个长为 \(n\) 的序列 \(a\) 定义 \(f(i,j)=(i-j)^2+g(i,j)^2\) \(g\) 是这样的一个函数 求最小的 \(f(i, ...
- 爬虫(14) - Scrapy-Redis分布式爬虫(1) | 详解
1.什么是Scrapy-Redis Scrapy-Redis是scrapy框架基于redis的分布式组件,是scrapy的扩展:分布式爬虫将多台主机组合起来,共同完成一个爬取任务,快速高效地提高爬取效 ...
- net core 3.1使用identityServer登录时signin-oidc报Correlation failed的解决方法
此问题全网找了很久,也困扰了我很久,始终没有找到解决方法.今天结合网上其他问题的帖子,自己研究的半天,终于找到了这个解决方法,经亲自测试可行.欢迎大牛指导指正. 有时客户收藏的系统地址是认证端的,然后 ...
- mysql面试题整理
1 myisam 和 innodb 引擎的区别 innodb 支持事务,外键,myisam 不支持 innodb 支持 mvcc ,myisam 不支持 innodb 支持表锁.行锁,myisam 仅 ...
- 零基础学Java(11)自定义类
前言 之前的例子中,我们已经编写了一些简单的类.但是,那些类都只包含一个简单的main方法.现在来学习如何编写复杂应用程序所需要的那种主力类.通常这些类没有main方法,却有自己的实例字段和实例方 ...
- 一些JS库汇总
作者:wlove 链接:https://www.zhihu.com/question/429436558/answer/2348777302 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权, ...