首页 > 其他分享 >ABC388DEG 题解

ABC388DEG 题解

时间:2025-01-12 23:55:13浏览次数:1  
标签:ABC388DEG cnt 题解 询问 扩展 回滚 端点 莫队

ABC388 题解

ABCDE+G,rk 371。

D

观察到几个性质:

  1. 一个人只会在成年的时候得到石头,在成年之后给出石头。
  2. 第 \(i\) 个人成年之后,他要给之后的每个人一个石头(除非用光了)。也就是说,假设成年时它的石头数量为 \(B_i\),则最终他的石头数量为 \(\max(0, B_i - (n - i))\)。

因此我们只需计算每个人在成年时会得到几个石头。这等价于询问他之前的人中,有多少人的石头数量 \(> 0\)。计算的方法很多。我在第 \(i\) 个人成年后,把 \(B_i + i\) 放到一个小根堆中,这个数就表示他能给到第几个人。(\(+ i\) 是为了统一)。统计第 \(i\) 个人成年时能得到几个石头,就弹出小根堆中所有 \(< i\) 的值,之后小根堆的大小就代表他能获得的石头数量。时间复杂度 \(O(n \log n)\),当然还有一些简单的线性做法。

不过这个做法还是稍微要点脑子,我也不保证我一定能想出来。我们有更直接的做法:直接模拟给石头的过程,用树状数组优化就行,只是码量略大。还是那句话:观察到的性质越多,代码就可以写得越简单。

E

结论:如果存在一个大小为 \(x\) 的匹配,那它一定可以表示为一个长为 \(x\) 的前缀和一个长为 \(x\) 的后缀匹配(即第 \(i\) 个元素匹配第 \((n - x + 1)\) 个元素)。

这个结论比较容易猜,但我不会严格证明。

有了这个结论之后,可以简单地用二分来得到答案。但实际上我们有线性做法,并且这个做法可以扩展到 G 的回滚莫队:

固定左端点 \(L = 1\),右端点 \(R\) 从 \(1\) 开始向右扩展,每次扩展时尝试更新当前的最大匹配 \(cnt\) 的值,\(R\) 扩展到 \(N\) 时 \(cnt\) 即为答案。(起初 \(cnt = 0\)。)这个结论是此做法的基础:我们只要知道最大匹配的大小,就能确定它的形态(即哪个元素和哪个元素匹配),这样就不用去记录匹配的形态。\(R\) 扩展到 \(R + 1\) 时,判断 \(cnt\) 是否会 \(+1\)。我们只需判断 \(A_{cnt + 1} \le 2A_{R - cnt - 1}\) 是否成立即可。有一个 corner case:当 \(cnt\) 的大于区间长度的一半就不用尝试更新 \(cnt\) 了,因为此时 \(cnt\) 不会变大。

G

区间询问,不强制在线,我们可以考虑用莫队来解决。根据 E 的线性做法,已经知道如何 \(O(1)\) 扩展,但如何删除呢?我们发现,要判断删除一个端点后 \(cnt\) 会不会 \(-1\),等价于判断:对于区间内长度为 \(cnt\) 的前缀和等长的后缀,前缀和后缀内的第 \(i\) 个数能否一一匹配,这似乎不太好维护。(实际上这可以转化为一个 RMQ 问题,见这篇题解。但能想到这个做法的话就不用莫队了)

但是我们还是能用莫队来做!对于这种扩展容易、删除困难的问题,可以用一种叫做“回滚莫队”的改版莫队来解决。这种算法可以在不能删除区间端点的情况下解决问题,并且时间复杂度和莫队一样都是 \(O(n \sqrt n)\)(假设询问次数 \(q\) 和序列长度 \(n\) 同阶,下同。)

还是把序列分成 \(B\) 块。对于每个询问,如果其左右端点在同一块,我们就暴力扩展处理,这样对于单个询问,时间复杂度是 \(O(n / B)\) (由于其左右端点在同一块,所以区间长度不超过 \(n / B\)。)否则,把询问按左端点所在的块分类,对于左端点在同一块的询问,我们一起处理。

具体而言,对于左端点在同一块内的询问,先按右端点大小从小到大排序。然后,还是用 \(L,R\) 和 \(cnt\) 表示当前处理的区间左右端点,和区间内最大匹配的大小。对于左端点在第 \(i\) 块的询问,初始化 \(L, R\) 为第 \(i\) 块的右端点,然后不断令 \(R\) 向右扩展。扩展到 \(R = j\) 时,如果有某个询问的左端点在第 \(i\) 块,而右端点为 \(j\),我们就处理这个询问。此时,\(R\) 已经到位了,但左端点还在原位,那么我们让左端点向左扩展,直到其到位为止。由于一开始 \(L\) 在第 \(i\) 块的右端点,所以 \(L\) 一直往左移动就能到位。但移动之后,对于之后的询问,\(L\) 可能就在它的左端点的左边了,而我们又不能删除,那怎么办呢?这里就是回滚莫队的精髓了:在 \(L\) 移动之前,我们先记录下移动前的 \(cnt\)。移动之后,直接把 \(L\) 和 \(cnt\) 修改为原来的值,就可以 \(O(1)\) 地回到移动前的状态,这就是“回滚”。于是,对于每个询问,我们都能保证 \(L\) 在其左端点的右边,这就规避了删除操作。

时间复杂度分析:处理左端点在一个块内的询问时,\(R\) 是单调增的,最多移动 \(n\) 次;对于每个询问,\(L\) 最多移动 \(n / B\) 次。因此处理左右端点不同块的询问,时间复杂度为 \(O(nB + \dfrac{n^2}{B})\),取 \(B = \sqrt{n}\) 最优,时间复杂度为 \(O(n \sqrt n)\)。而处理左右端点同块元素的时间复杂度是相同的,因此这就是回滚莫队的时间复杂度。

参考代码

(回滚莫队练习题)「JOISC 2014 Day1」历史研究

这不是这场 ABC 的题,但刚学回滚莫队,把这道题就一起放这里了吧。

这道题扩展是容易的,因为序列中的数都是正数,所以一个数的重要值单调不降,整个区间的最大重要值也单调不降,因此每次更新一个数的重要值后,都可以尝试用它来更新区间的最大值。但删除是困难的,因为一个数的重要值单调不升,而原先的区间最大值变小之后难以快速更新。扩展容易删除难,这就是回滚莫队典型的应用场景。

在回滚莫队中,除了区间的扩展,还有一个重要的部分是回滚。这道题的回滚比 G 稍微复杂一些(但也还好):扩展之后,重要值数组会更新。如果我们拷贝整个重要值数组,回滚的时候再赋值回来,时间复杂度接受不了。不妨用一个 vector 记录下将要扩展的区间的数当前的重要值,回滚的时候重新赋值就行了。

标签:ABC388DEG,cnt,题解,询问,扩展,回滚,端点,莫队
From: https://www.cnblogs.com/dengstar/p/18667635

相关文章

  • LeetCode 2275: 按位与结果大于零的最长组合题解
    LeetCode2275:按位与结果大于零的最长组合题解1.题目分析这道题目考察了位运算的基本概念和应用。我们需要在给定的数组中找出最长的子序列,使得这些数字进行按位与运算后的结果大于0。1.1关键概念按位与运算(&)两个二进制位都为1时,结果为1。只要有一个为0,结果就为0......
  • 【大数据】beeline 导出文件有特殊字符的问题解决
    问题近期在做大数据查询引擎导出文件的功能,使用了hive的beeline客户端。发现beeline导出的文件以及终端输出有许多特殊字符。按照官方文档使用beeline导出命令:[1]/usr/bin/beeline--silent=true--showHeader=true--outputformat=csv2-fquery.hql</dev/null>/tm......
  • Hetao P3804 Cut 题解 [ 蓝 ] [ AC 自动机 ] [ 差分 ]
    Cut:AC自动机简单题。思路看见多个模式串以及求前缀,很显然能想到构建一个AC自动机。那么在用\(T\)查询时,当前指针的深度就是该位置的最长前缀匹配长度。这个在字典树insert的时候就能求出来。求出每一位的最长前缀后,因为这些部分都不能作为分割点,所以将这些区域用差分......
  • 验证出栈顺序是否正确题解&队列
    (1)验证出栈顺序是否正确队列遵循先入后出的原则,故需要一个数组来模拟记录入栈和出栈再分别对出栈顺序进行遍历验证是否正确#include<iostream>usingnamespacestd;#definem100000intb[m],a[m],c[m];intmain(){ intt; cin>>t; while(t--){ intn;......
  • THUWC 2020 Day3 题解
    Cache一致性协议按照学习手册最后的模拟。\(\text{Exclusive}/\text{Shared}\)只有编号最小的返回,但都要改变状态。\(\text{Modified}\)的所有的都要返回且改变状态。Cache替换算法这里说一下\(\text{PLRU}\)算法。对于每次,先找是否命中。如果是否,就在二叉搜索树上......
  • 2021 年 3 月青少年软编等考 C 语言五级真题解析
    目录T1.红与黑思路分析T2.密室逃脱思路分析T3.求逆序对数思路分析T4.最小新整数思路分析T1.红与黑有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计......
  • Codeforces Round 734 (Div. 3) 题解
    建议开题顺序:A,B1,B2,C,E,F,D1,D2。A.PolycarpandCoins记\(k=\min(c1,c2)\),则\((c1-k)\times1+(c2-k)\times2+k\times3=n\)。注意到\(n\mod3\)为\(0,1,2\)。所以我们\(|c1-c2|\)最多为\(1\),只需要将\(n\mod3\)给\(1\)或\(2\)即可。B1.WonderfulColo......
  • P5025 [SNOI2017] 炸弹 题解
    题意link.题解我们充分发扬人类智慧。考虑到可能连锁爆炸,我们不能通过一个单纯的二分来解决问题。考虑\(dp\)。记\(f(i)\)为第\(i\)个点爆炸,最远能引爆到哪个坐标小于它的点。\(g(i)\)为第\(i\)个点爆炸,最远能引爆到哪个坐标大于它的点。我们以\(f\)为例,\(g\)......
  • AT_abc388_f Dangerous Sugoroku 题解
    太幽默了。显然可以用矩阵快速幂解决,矩阵里维护距离当前点\(B\)以内的所有点可不可达,转移只需分段,在区间内和不在区间内用不同的转移矩阵即可。复杂度\(O(B^3m\logn)\)。然后你就T了。此时你很急,你现在应该快点卡常来AK这场比赛而不是研究其他的做法,于是我们发现快速幂......
  • Atcoder ABC388F Dangerous Sugoroku 题解 [ 蓝 ] [ 矩阵加速 ] [ 状压矩乘 ] [ 模拟
    DangerousSugoroku:赛时写了矩乘T飞了,受到sunkuangzheng大佬的启发才知道要状压矩乘。暴力矩乘思路直接像过河那样写模拟细节非常多,于是考虑像美食家一样的思路,利用矩阵分段加速。定义\(dp_i\)表示\(i\)能否到达,则有如下转移:\[dp_{i}=\bigvee_{j=i-B}^{i-A}dp_{j}\]......