贪心

概述

  • 贪心用于解决最优化问题。

  • 例题之前的都是某次听大牛讲课的产物,可以认为,这一篇目前只是胡乱地把贪心相关的东西堆砌在一起,没有什么应有的逻辑结构。换言之,这没完工,只是建材。

组合问题

  • 考虑给定一个集合 \(U\),对 \(U\) 的子集进行询问。

组合判定

  • 考虑给定一个集合 \(U\),一个限制条件 \(P\),问是否存在 \({A\subseteq U|P(A)}\)

  • 一般化地,称 \(I={A\subseteq U|P(A)}\),这里 \(I\) 是一个集族,即集合的集合。

组合构造

  • 给定 \(U,P\),判断是否 \(I=\varnothing\)。如果不是,则求一个元素 \(A\in I\)

组合最优化

  • 给定估价函数 \(f(A)\),求 \(f(A)_ {max}\)

组合计数

  • \(I\) 的大小。

拟阵贪心

  • 考虑一种组合最优化问题,其中 \(f(A)=\sum\limits_{x\in A} v(x)\)

  • 容易证明,如果满足以下两个条件,那么可以逐 \(k\) 个元素地贪心:

    • \(\forall A\in I,\forall B\subseteq A\in I\)

    • \(\forall A,B\in I\And|A|-|B|=k\)\(\exists\ C\subseteq A,|C|=k\And (B\bigcup C)\in I\)

  • 拟阵似乎和凸包有一些我尚不了解的关系,否则解释不了为什么带悔贪心和 wqs 有时等效。(信息来源:瞥到的小粉兔的回帖)

带悔贪心

  • 带悔贪心是一种用于 \(f(A)=\sum\limits_{x\in A} v(x)\)\(P(A)\) 有特殊性质的组合最优化问题的贪心。

  • 空口无凭,给我例题。

ABC218H

  • 题意:共 \(n\) 个球排成一列,选出 \(m\) 个染成蓝色,其余为红色。如果 \(c_i\neq c_{i+1}\),那么获得 \(v_i\) 的收益。求最大收益。

  • 数据范围:\(1\leqslant m<n\leqslant 2\times 10^5,0<v\leqslant 10^9\)

  • 首先我们做一个题意转化,即 \(m=\min(m,n-m)\)。于是我们染的蓝球数量一定 \(\leqslant \dfrac{n}{2}\)

  • 容易证明一定不会把相邻的两个球都染成蓝色。

  • 结论1:除非 \(n\) 是奇数并且我们恰有 \(m=\lfloor\dfrac{n}{2}\rfloor\),否则任意的有贡献的一段的段长一定为偶数(相邻段合并)。

    • 上面这个除非,其实是说我们取得了所有 \(v\),且 \(n\) 是奇数,故为奇数。\(n\) 是偶数的时候全部取得显然也是偶数。

    • 不全部取得的时候,假设某一段有贡献的长度为奇数,则该段必然为 \([1,x]\)\([x,n]\),且 \(c_1=1\)\(c_n=1\)\(1\) 为蓝色),此时一定可以通过调整的方式多获得某个点的 \(v\)

  • 结论2:我每染一个球,必然获得一个新段的两个 \(v\),或将已有的某个段向左/右延伸各 \(1\) 的长度。

    • 前者显然。注意我们说的是极大子段。

    • 后者的话...将 \(l\) 处染色(显然 \(l\) 处以前一定没有染色),然后将 \(l+1\sim r+1\) 的颜色反转。显然我确实只多染了一个。这就是某种“反悔”:本来染的是奇数编号的球,现在变成偶数编号的了。

  • 那...就很板了对吧。直接用 p_q 维护区间就好咯。区间合并?嗯...用链表,用过的点从链表中删掉。

P1484 种树

  • 题意:\(a_n\)\(m\) 个,相邻两个不可同时选。\(f(A)=\sum\limits_{x\in A} v(x)\)

  • 数据范围:\(n\leqslant 5\times 10^5,m\leqslant \dfrac{n}{2},-10^6\leqslant v\leqslant 10^6\)

  • 可以看到这个和上面那个的形式并不太一样(那是边权这是点权)。不过我并不是以此为最大目的。

  • 上面那个贪心在反悔时,并不用真的反悔,即,不用真的把得过的分失掉。这个显然是要的。

  • 容易想到分奇偶性做前缀和每次暴力(对,正在写博客的这个小[数据删除]真的干过这事)。

  • 好吧我们来谈正经的。怎么标记已经被选过的点?

  • 答案是可以这样做(这不比我一开始乱嘴的优雅多了?):

    • 初始时每个点对应的决策都是“选我不选两边”。该决策的 \(id=i\)\(id\) 是用于判 \(vis\) 或者说 \(occu\) 的。

    • 当选了某个决策,将它的 \(pre\)\(nxt\) 决策的 \(id\)\(vis=1\)。即,对应决策不可用。容易证明我的 \(pre\) 决策一定要求把我的左边界的左边的地方的树种上,反之亦然,故对应决策不再可用。

    • 什么,还可以翻转上述操作?嗯,很对。于是此时将我的 \(v\) 改为 \(v_{pre}+v_{nxt}-v_{now}\)。即,执行前驱决策和后继决策,将我这个决策翻转;这三个联合起来组成了一个新决策!

  • 这不优雅死?

CF739E Gosha is hunting

  • 我觉得很神妙的一个题,刷新了我对 wqs 和贪心的认知。

  • 题意:有 \(n\) 只精灵,\(A\) 个普通球,\(B\) 个超级球。给出 \(Pa_n,Pb_n\) 表示抓到的概率,求抓到精灵数的最大期望。

  • 数据范围:原题 \(n\leqslant 2\times 10^3\)。用神妙写法可以过 \(n\leqslant 10^5\)。如果用一点 nth_element 相关优化可以进一步扩大到 \(n\leqslant 10^6\)(然而在我的实测里不太有效...难道又是 STL 的 feature?至少 KDT 那里它是很快的啊)。

  • 首先我们容易证明,固定一种的使用数量之后,总期望一定是一个关于另一种的使用数量的凸函数。

  • 从而我们可以暴力枚举一种的使用数量,另一种暴力 wqs...等等,怎么 check?

  • 唔...好问题。先谈谈带悔贪心的思路?

  • 可以。暴力选出 \(Pa\)\(A\) 大的,然后我们的决策无非是选一个没被选过的 \(Pb\),选一个被选过的 \(Pb\) 和选一个被选过的 \(Pb\) 并把对应的 \(b\) 类球换到别的地方三种。

  • 显然我们可以 \(O(n\log n)\) 地处理出所有决策。感觉可以优化哈,每次决策后,一类决策最多减少一个(对应决策变成二/三类的),二类决策最多减少一个,三类决策也最多减少一个(换到的地方在每轮决策中显然是唯一的)。

  • 所以应该可以用 multiset 之类乱搞优化到 \(O(n\log^2 n)\),不过不谈了。

  • 回过头来谈怎么 check。在 wqs 意义下,我们其实是有“无数多个”二类球,所以我们先暴力把所有 \(Pb-K>0\) 的都选上,然后来做决策。显然此时被弹走的二类球无处可去,所以决策集几乎不变,用 nth_element 代替快排可以 \(O(n^2\log n)\)

  • 等下。我们知道,这个图像如果拉成三维的,那么它是一个广义的双参凸函数;但由固定一类球的使用数量而定下来的单参凸函数应该是彼此独立的!我们好像只用对钦定用了 \(A\) 个的那个函数求解吧?

  • 于是这也是 \(O(n\log^2 n)\) 的,用 nth_element 理论为 \(O(n\log n)\)

  • 直接做 wqs 套 wqs 的 \(O(n\log^2 n)\) 做法,直觉上很可能是对的,然而是假的。理由如下:朴素 wqs 其实是要截一个合法区间,可是多维的合法区间没有平凡的维护方法。

  • 对于只有一维的 wqs,我们的合法区间是截到的线段在 \(x\) 轴上的投影线段,也即一个区间。要看这个斜率合不合法,只要看限制的数量是否在这个区间内即可。

  • 然而高维 wqs 截得的平面或超平面抛弃掉 \(dp\) 值这一维之后还有至少两维,以二维 wqs 为例就是合法区间是 x-y 平面上的一个投影,其应当是一个多边形或者什么东西。

  • 一维的时候,我们可以简单判断限制数量是否在区间内;二维的时候,我们就得判断限制的数量 \((x,y)\) 是否在这个多边形内。

  • 首先我们不知道怎么判断是否在其中,然后我们也不知道要怎么记录这个多边形,最后,一维 wqs 我们只要知道区间的左右端点也即最多 dp 两次,而要知道这个多边形我们要怎么 dp?!

例题

P2123 皇后游戏

  • 题意:

    • 给出一个序列 \(m_{1\sim n}\),每个元素有两个属性 \(a,b\)

    • 求一种排列,使得 \(\max_{i=1}^n(c_i)\) 最小。

    • \(c_i=\begin{cases} a_i+b_i & i=1 \\ \max(c_{i-1},\sum\limits_{j=1}^i a_i)+b_i & otherwise\end{cases}\)

  • 数据范围:\(T\leqslant 10,n\leqslant 2\times 10^4\)

  • 发现这东西...很像国王游戏。虽然我们还没有归类,但不妨把它们称作“邻项交换式贪心“。其特点如下:

    • 问题具有某种意义上的序列递推性;

    • 交换相邻两者具有一定的孤立性,至少没有后效性(对前面的结果不影响);

    • 可以对邻项求出一定的偏序关系使得满足它时最优,且该偏序关系可以推广到整个序列,进而排序解决。

  • 首先我们暴力拆式子,乱化一通后得到这个,其中 \(s_i=\sum\limits_{j=1}^i a_i,sum_i=a_i+b_i\)

\[c_{i+1}=\max(c_{i-1}+b_i+b_{i+1},s_{i-1}+sum_i+b_{i+1},s_{i-1}+a_i+sum_{i+1}) \]

  • 如果是首项,那么邻项交换无意义;

  • 如果是后两项之一,那么我们关心的其实是 \([\max(sum_i+b_{i+1},a_i+sum_{i+1}) \leqslant \max(sum_{i+1}+b_i,a_{i+1}+sum_i)]\),后者是交换之后的结果。

  • 式左右同乘 \(-1\) 然后加上 \(sum_i+sum_{i+1}\),简单变号(拆负号会导致 \(\max/\min\) 互换)得到 \([\min(a_{i+1},b_i)\geqslant \min(a_i,b_{i+1})]\)。该式值为 \(1\) 则不换,否则换。

  • 然后 sort 之,提交,\(\text{WA 20pts}\)

  • 这是因为,该偏序关系不是严格弱序。所谓严格弱序,是满足以下四个条件的偏序关系:

    • \(\forall x,x\nless x\)(非自反性,即元素不与自己构成偏序);

    • \(\forall x<y,y\nless x\)(非对称性,即对称的偏序不能同时成立,必有一假);

    • \(\forall x<y \land y<z,x<z\)(传递性,略);

    • \(\forall (x\nless y \land y\nless x) \land (y\nless z \land z\nless y),x\nless z \land z\nless x\)(不可比性的传递性,即偏序的不成立——双向不成立——也具备传递性)。

  • 我们给出的偏序关系满足前三条,但不满足第四条。

    • 非自反性:可以考虑把我们的 \(<\) 关系改成 \(>\),于是不等号的等号被拆掉了,容易证明两个偏序关系同构,所以我们的偏序关系满足非自反性。

    • 非对称性:证明显然。

    • 传递性:需要分类讨论,这里略去。

    • 不可比性的传递性:显然不成立,不妨考虑 \((3,5),(1,1),(2,7)\),发现邻项不可比(注意,这导致该偏序稳定!),但跨项可比。

  • 解决办法:想办法进一步限制它的不可比情况。

    • 我们偏序关系的正确性其实是显然的,问题主要在于中间插着几个不可比项的时候,会阻止我们需要比的项进行比较(我 \(\text{ABC277F}\) 的假做法问题其实就在这里)。

    • 所以解决办法就是随便加一个合理的偏序,在 \(\min=\min\) 的时候判一下。本题可以放 \(a_i<a_j\)\(b_i>b_j\),毕竟我们的偏序本身是对的,只要用任意的合理手段破坏掉不可比性,将偏序变成全序即可。

  • 于是问题解决。总复杂度 \(O(n\log n)\)

[AGC009D] Uninity

  • 题意略。

  • 首先容易发现点分构造可以把上界卡到 \(O(\log)\)

  • 考虑贪心,显然叶节点是 \(0\),则考虑贪心地把其父节点置为 \(1\)

  • 手推样例发现有小问题,譬如 \(fa\) 的各个儿子分别是 \(0,1\),则 \(fa\) 必须是 \(2\);但若 \(fa\) 的各个儿子分别是 \(0,0,2\),则 \(fa\) 本身可以填 \(1\),从而 \(fa\) 这棵子树是 \(2\) 而非 \(3\)

  • 猜测相邻两个 \(k\) 之间至少要有一个 \(>k\) 的数作为“分水岭”。按此模拟即可,因为值域不超过 \(O(\log)\)。当然也可以考虑三进制状压。

[AGC037B] RGB Balls

  • 题意略。

  • 容易构造一种最优解,即贪心地在还能取的球中取一组尽量靠前的。正确性在直觉上显然。

  • 考虑从前往后扫这个序列,把所有球都拿到手里等着接后面的。手推样例,譬如 BBGGRR,直觉上发现靠前的 G 和靠前的 R 给哪个 BBG 没有影响。

  • 但在 BBGRRG 中,第一个 R 如果给 B,则为 \(4+4\),否则为 \(3+4\)

  • 故猜测每次如果能结束必须结束,否则能接就接,给谁随意。至于给哪个,容易证明同时只会有一种选择(不考虑二元组的顺序)。

  • 一个较为精巧的证明是,认为每走一格就要付出手上的未完成三元组数量的代价。故尽量早结束,同理,尽量接以便尽量早结束。

  • 模拟即可。

[AGC028E] High Elements

  • 题意略。

  • 首先,容易想到按位贪心。考虑怎么 check。

  • 不妨分别记两序列(尝试在这一位上放 \(0\) 以后的两序列)的前缀最大值为 \(mx_1,mx_2\),前缀最大值个数为 \(cnt_1,cnt_2\)

  • 于是问题变成在 \(O(\log)\sim O(\sqrt{n})\) 的时间内,check 是否存在一种后续的放 \(0/1\) 方式,使得 \(cnt_1+k_1=cnt_2+k_2\),其中 \(k_1,k_2\) 分别为两序列以后的最大值更新次数。

  • 结论 \(1\):原序列的前缀最大值(称为“旧的”)一定还是某个序列的前缀最大值(称为“新的”)。

    • 非常显然,证明从略。
  • 结论 \(2\):任意合法构造都可以转化归约到某一个序列中的前缀最大值全是旧的的构造上。

    • 不妨假设 \(A\) 中有至少一个新的,则把它丢到对面,显然使它不是前缀最大值的那个或那些数,在放它时已经在它前面。

    • 同理把对面的一个新的丢过来,于是 \(cnt_1,cnt_2\)\(-1\),仍然合法。

  • 不妨设(对称的两种都试一下)以后的 \(A\) 中全是旧的,并记以后的 \(B\) 中有 \(k_1\) 个旧的,\(k_2\) 个新的,记共有 \(all\) 个旧的。

  • 于是对于任意长的 \(01\) 序列的前缀,其合法,当且仅当 \(cnt_1+(all-k_1)=cnt_2+(k_1+k_2)\)

  • 变换得到 \(cnt_1-cnt_2+all=2k_1+k_2\)。式左为定值,式右相当于剩余的原序列在“旧的记两次,新的记一次”意义下的 LIS 长度。

  • 然后我们可以证明,如果 \(2k_1+k2=x(x\geqslant 2)\) 成立,那么 \(2k_1+k_2=x-2\) 也成立。因为我们可以把一个 \(k_1\) 丢到对面去,在这个式子的意义下相当于 \(-2\)\(k_1\) 不够就扔 \(k_2\)

  • 故我们要验证的其实是某一段后缀的带权 LIS 在奇偶情况下分别的最大值。显然可以 \(O(n\log n)\) 实现,然后按位贪心即可。

[AGC007F] Shik and Copying String

  • 题意:给出字符串 \(S\),每次操作可以将 \(S_i\) 变为 \(S_{i-1}\) 或不变(从左向右考虑这个过程),求令 \(S=T\) 的最小操作次数。

  • 数据范围:\(|S|,|T|\leqslant 10^6\)

  • 从右向左考虑 \(T_i\),不妨称 \(T_i\)\(S_0\) 中的来源为 \(fr_i\),则 \(fr_i=\max_{j=1\sim fr_{i+1}-[T_i\neq T_{i+1}] \And [S_j=T_i]} j\),即可以认为是把 \(T\) 中连续段合并到左端点后,\(S\) 中还未被覆盖的 \(T_i\) 中最靠左的一个。

  • 这一匹配是容易的,双指针扫一遍即可。问题是:如何知道操作要做几次?毕竟多个字符的扩展可能是相互掣肘的。

  • 考虑画出网格折线图,上方为 \(S_0\),下方为 \(T\),在 \(fr_i\)\(i\) 之间连边,当然是折线,第 \(i\) 行第 \(j\) 列(行自 \(0\) 始)为操作 \(i\) 次后的 \(S_j\)

  • 故发现若从右向左考虑 \(T\),则已有的折线构成一个“折线壳”。不妨定义拐点为 \(S_j=S_{j-1}\)\(j-1\),则可以得出如下结论:

  • 每次为 \(T_i\) 加入新的变换时相当于在这个壳左下方再套一层,换言之,把所有和 \(i\) 同列或在左边的折点向左、下各平移一格,其余折点删掉,可能创建一个新的折点。

  • 任意时刻的折点数目除二都为答案的一个下界。折点可以用队列+偏移维护之(当然远没有说得这么容易...),总复杂度应为 \(O(n)\)

[AGC023F] 01 on Tree

  • 题意略。较典的一类题中的一个子类?

  • 首先我们知道,如果能取 \(0\),无脑取 \(0\)。又显然自顶向下的做法不可做,有多个 \(1\) 时退化成 \(k\) 关键字排序,故考虑自底向上,先把所有 \(0\) 连给它们的非 \(0\) 父亲。

  • 此时应该剩下一车 \(1+x0\),当然根节点可能没有 \(1\)。考虑怎么进一步合并这个东西,换言之,如果我已经把这棵子树的大门叩开,我应该在其中整怎样的顺序?

  • 这里有一个奇怪的假定:对于一个父亲来说,一旦解锁了某个儿子,就会一下子把它出完。没有见到证明。

  • 但在此基础上,我们可以考虑邻项交换贪心。已知各个儿子方向的 \(cnt_{0/1}\),设 \(i\)\(j\) 更优也即更早出,则有 \(cnt_{i,1}\times cnt_{j,0}\leqslant cnt_{j,1}\times cnt_{i,0}\to \dfrac{cnt_{i,1}}{cnt_{i,0}}\leqslant \dfrac{cnt_{j,1}}{cnt_{j,0}}\)

  • 注意一下除零,然后用 multiset 之类维护一下即可。

P4437 [HNOI/AHOI2018] 排列

  • 题意:试构造一个合法排列 \(p_{1\sim n}\),使其权值最大。

    • 合法排列:设有 \(a_{x_1,x_2,\dots ,x_k}=v\),则 \(p\)\(v\) 的出现必须早于 \(a_x\) 的出现。这里 \(a_i\in [0,n]\)

    • 权值:对于排列 \(p_{1\sim n}\),其权值为 \(\sum\limits_{i=1}^n i\times w_{p_i}\)

  • 数据范围:\(n\leqslant 5\times 10^5\),保证答案不炸 ll。

  • 首先注意到 \(0\sim n\) 这些数字构成某种拓扑关系,当然我们不会填 \(0\),或者说总是已经填过 \(0\)。可以以此拓扑排序判无解。

  • 然后考虑怎么求最大权值,自然而然想到一个拓扑排序,但显然是错的。

  • 参考上一题思路,想到合法时构成一个以 \(0\) 为根的树,于是考虑对连通块维护 \(wsum,sum,cnt\) 分别表示带权和(权即为在块内序号),和还有块内点数或者说数字数。容易合并,即下式:

\[\begin{cases} wsum=wsum+sum'\times cnt+wsum' \\ sum=sum+sum' \\ cnt=cnt+cnt'\end{cases} \]

  • 那么一个直观的贪心是每次选出全局 \(sum\) 最小的,毕竟我们希望小的往前放嘛,等效于大的往后放,而显然倒序考虑很麻烦甚至可能不可做。

  • 但显然是错的,仔细思考发现这个还是个邻项交换模型,即:

\[sum'\times cnt+sum''\times (cnt+cnt')\geqslant sum''\times cnt+sum'\times(cnt+cnt'') \]

  • 于是:

\[sum''\times cnt'\geqslant sum'\times cnt'' \]

  • 即:

\[\dfrac{sum''}{cnt''}\geqslant \dfrac{sum'}{cnt'} \]

  • 好了,那么用 \(\dfrac{sum}{cnt}\)\(pri\) 就好了,每次在全局贪出来 \(pri\) 最小的合并给父连通块,使用并查集容易维护。

  • 总复杂度 \(O(n\log n)\)

P4785 [BalticOI 2016 Day2] 交换

  • 题意:给出 \(1\sim n\) 的排列 \(a_{1\sim n}\),对于 \(i=2\sim n\)(按升序顺序),可以交换 \(a_i,a_{\lfloor\frac{n}{2}\rfloor}\) 或什么都不做。求能构造出的字典序最小的排列。

  • 数据范围:\(n\leqslant 2\times 10^5\)

  • 首先手推发现 \(a_1=\min(a_1,a_2,a_3)\),但当 \(a_1=a_3\) 时第一次是否交换是无所谓的,决策权转到 \(a_2\) 上,进一步模拟这个过程发现对合适的 \(a_{1\sim 5}\),操作序列可能是 (NY/YY)(NY/YY),乍一看是指数级的情况数但仔细思考发现这个链长度为 \(\log_2\),故单链的实际情况数只有 \(n\)

  • 尝试进一步计算链数,发现各部分互相影响非常难以算出。凭直觉已经有了一个做法:每次暴力向下搜两步,然后把非最优的状态删掉。至于对不对...我猜复杂度不超过 polylog,但没有写过,不予置评。

  • 考虑用更清晰、更形式化地方式描述这个过程。注意到题目允许的交换其实构成了一个类似完全二叉树的下标关系,我们把这棵完全二叉树建出来,考察一下最终排列中的每个点到底能是原排列中的哪些点,发现首先可以是左右儿子,然后可以是祖先,还可以是走一条右链能回溯到的祖先的左儿子。

  • 显然总决策量是 \(O(n\log)\) 的,问题是怎么确定到底可以是哪些点。从 \(b_1=a_3\) 的情况可以看出,左右儿子应该是不独立的,考虑用 bfs 序遍历这棵树,首先是把每个点的集合置为 \(ls,rs\),然后把 \(1\) 给它自己,然后...

  • 别,大哥,别。这样一来我们就又回到上面那个恶心的...分讨?里面去了。考虑转而记录已经决定的点对当前点有什么限制,显然不可能限制其从左右儿子中获得最小值,可能限制其从祖先方向(包括自己)获得最小值。

  • 进一步考察之后,发现不妨将节点按 \(b_i\) 的来源分为三类:

    • 从祖先来:其子树中的所有点都不可以到达或越过它,其右子树也不可以碰它的左儿子,因为向下的交换根本没有发生。

    • 从左儿子中来:左儿子可以越过它,从祖先获得一个值。

    • 从右儿子中来:其能提供以下两种效果之一。

      1. 左儿子可以从祖先获得一个值,右儿子可以获得这个左儿子。

      2. 右儿子可以从祖先获得一个值。

    • 注意,这两个效果是互斥的,但第一个效果中的两个决策不是绑定的,即可以只干其中一件事。大力分讨,细节地狱。

  • 那么这就是一个可以接受的分讨了,按 bfs 序暴力回溯祖先即可,复杂度 \(O(n\log)\)

[AGC018B] Sports Festival

  • 题意略。

  • 我首先想到了如下做法:

    • 暴力枚举第一个项目选哪个。然后不断地贪参与人数最少的项目,将它开展。

    • 显然过程中已经开展的项目参与人数和可能准备开展的项目的参与人数是不增的,故这一贪心应该是对的。

    • 枚举第一个项目 \(O(n)\),接下来 \(n\) 轮,取参与人数最少的项目姑且也认为是 \(O(n)\) 暴力扫过去,但怎么维护"将会参与人数"?其实这有些像不优化的 Prim...摊还分析?

  • 然而事实上并不可分析。正难则反,考虑一开始把所有项目都开展,不断毙掉参与人数最多的项目,去了一个 \(n\)。如果对每个人维护一个指针还可以再去一个 \(n\),于是 \(O(n^2)\),且这个贪心的正确性更加显然,因为不毙掉参与人数最多的项目就一定没有希望减小答案,多个最多随便选一个显然是对的,因为需要都毙掉。

UOJ #702.张飞卷精兵

  • 题意略。

  • 显然淘汰赛我们应该建竞赛树。然而我赛时对着 leafy 的重构树卡死...

  • leafy 重构树的一个巨大缺点是其叶子是平等的,看不出叶子之间的关系(如果它们之间有某种限制之类的话)。作为对比,nodey 的重构树则允许我们做一些操作。

  • 考虑建立 nodey 的重构树,每场比赛中的败方向胜方连边。显然有 \(2^n\) 个精兵的重构树会有 \(n+1\) 层,容易证明的是,其奇数层(自上而下从 \(1\) 开始标号)为正贡献,偶数层为负贡献。

  • 不妨将精兵按实力降序填入这棵树,于是一开始只有根节点可用,填了某个点后其的所有子节点可用。一个显然的贪心是,如果有偶数层就填偶数层,否则填儿子最多的奇数层。

  • 这是对的。因为偶数层一定是一出现就被填完,它们之间的相对顺序关系无所谓;而奇数层,不妨设 \(2^n\) 个点的重构树为 \(T_n\),于是可以发现 \(T_n\) 相当于一个根下面挂了 \(T_0\sim T_{n-1}\) 各一个,换言之所有 \(T_n\) 同构,从而直接按度数/子树大小贪就是对的。至此可以获得一个 \(O(2^n\log n)\) 的做法(直接对每类奇数层点计数,所谓种类指的是 \(T_x\) 的根为 \(x\) 类点)。

  • 有没有感觉这个操作很典?这让我们想到 01 on tree。不妨首先抛弃掉偶数层点,当我们填了一个奇数层的 \(x\) 类点时,我们会解锁 \(x\) 个偶数层点,它们显然构成了一个公差为 \(2\) 的等比数列,操作之即可;这些偶数层点分别是 \(0\sim x-1\) 类点,考察发现 \(x\) 类点的度数也为 \(x\)(这是显然的),于是一共解锁了... \(1\sim x-1\) 会解锁 \(0\) 类,\(2\sim x-1\) 会解锁 \(1\) 类,哦就是第 \(y<x\) 类的奇数层点会解锁 \(x-y-1\) 个。

  • 点的类数只有 \(n+1\) 类,显然同类的奇数层点是一起出的(后面扯着一车偶数层点并会解锁一些奇数层点),它们作为奇数层点本身的正贡献显然构成等比数列,而每个点挂的偶数层点本身构成等比数列,这些等比数列之间又构成等比数列。换言之,这些都可以在 \(O(n\log mod)\)(因为要求逆元之类的)的时间内解决,唯一的问题是我们需要对那个奇数层每类点的数量加等差数列,这显然可以通过线段树维护,也是 \(O(n\log)\)

  • 01 on tree 中的“向父亲合并的全局邻项交换式贪心”并没有用到。这主要是我们的树的同构性带来的。

posted @ 2023-01-11 15:08  未欣  阅读(29)  评论(0编辑  收藏  举报