其他分享
首页 > 其他分享> > P5979 [PA2014]Druzyny

P5979 [PA2014]Druzyny

作者:互联网

题面

体育课上,\(n\) 个小朋友排成一行(从 \(1\) 到 \(n\) 编号),老师想把他们分成若干组,每一组都包含编号连续的一段小朋友,每个小朋友属于且仅属于一个组。

第 \(i\) 个小朋友希望它所在的组的人数不多于 \(d_i\),不少于 \(c_i\),否则他就会不满意。

在所有小朋友都满意的前提下,求可以分成的组的数目的最大值,以及有多少种分组方案能达到最大值。

数据范围:\(n\le 10^6\)。

题解

首先肯定有 \(n^2\) dp,设 \(f_i\) 表示只考虑 \(1\sim i\) 小朋友的情况下的最大值和方案,这里定义 \(+\) 为 \(f\) 的运算,有转移:

\[f_i=\sum_{j=1}^{i-1} (f_{j}+1) \;\;\;\;\;\;\;\;\left(\max_{j< k\le i} l_k \le i-j+1\le \min_{j< k\le i}r_k\right) \]

考虑优化这个dp。

首先要注意 \(\le (\min_{j< k\le i}r_k)\) 这个限制是好做的,因为设 \(g_i\) 表示最小的 \(j\) 使 \(j\) 满足限制,那么 \(g_i\) 是单调不降的。

所以我们可以预处理出 \(g_i\) ,那么dp就成了:

\[f_i=\sum_{j=g_i}^{i-1} (f_{j}+1) \;\;\;\;\;\;\;\;\left(\max_{j< k\le i} l_k \le i-j+1\right) \]

因为有 \(\max\) 这种东西,我们可以考虑 cdq分治优化dp,然后就是一个二维偏序,这就是好做的。

所以就有 \(n\log^2 n\) 的做法。但是 \(n=10^6\) ,这还不够优秀。

因为有区间 \(\max\) 的存在,我们可以考虑笛卡尔树分治!这样对于一组 \((l,r,mid)\),\(\forall x\in[l,mid),y\in[mid,r],f_x\rightarrow f_y\) 时,\(\max_{j< k\le i} l_k= l_{mid}\) !

但是笛卡尔树分治我们不能保证 \(mid\) 两边的区间大小尽量一致啊,这样怎么保证复杂度?

参考上文,我们知道除了保证大小一致,我们还可以让一次分治 \(x+y\rightarrow x,y\) 的复杂度达到 \(\min(x,y)\) ,那么总复杂度也是 \(n\log n\) 的。

现在考虑一下我们的转移,记 \(k=l_{mid}\):

对于 \(y\in[mid,r]\) ,合法的 \(x\) 的范围是 \([\max(l,g_y),\min(mid-1,y-k)]\) 。

考虑把 \(\max,\min\) 去掉:

所以对于操作二和操作三中的整体查询/修改,我们可以通过线段树维护,一次分治只会操作一次,所以是 \(O(n\log n)\) 的,而操作三中的扫描一遍的复杂度是 \(\min(x,y)\) 的,所以这部分也是 \(O(n\log n)\) 的,所以就有 \(O(n\log n)\) 的做法。

启发

标签:le,log,min,max,PA2014,分治,mid,Druzyny,P5979
来源: https://www.cnblogs.com/qwq-123/p/16492240.html