C1
没有修改。
我们直接模拟人排队的过程。枚举 的每一个元素 ,看看当前 数组的头部是不是和 相等,若是,将 移到某个位置;否则就 No。
问题来了,每次怎么移动 呢?
我们发现并不需要显式地移动,只需把用过的 丢到一个集合里,想用的时候拿出来就行,因为可以移到任意位置。
每次判 的时候多看一眼这个集合里面有没有 。如果有,那 这个元素就合法。
进一步地,我们还不需要显式地弄出这个集合。我们发现,我们只关心 中每个元素被丢进集合的时间戳 。记元素 在 中出现的位置为 ,那么判 的时候只需要看看是否 即可。
那么这个 等于多少呢?显然等于 中第一个出现 的位置。
于是就做完了,时间复杂度 。
C2
现在带修了,我们考虑如何快速判断合不合法。
我们(通过归纳手玩)注意到合法等价于 是升序的。原因在于,若不升序,记 且 。在 这个时刻,我们需要 这个人出来放幻灯片,但是前面 这个人没有走,卡住了 ,于是不合法。升序当然合法。
也就是说,我们只需要单点修改 ,全局判断是否升序即可。
如何单点修改 ?
我们对每个 中的下标开个 set,记录在 中出现的位置。于是实时的 就是 set 中的最小值。
修改只需变更 set 中的元素。
每次对于 ,需修改 和 。
如何判断升序?
讲一个 set 的做法。
升序(这里的升序并非严格,为处理方便将 中某些元素设为 )等价于差分数组的最小值大于等于 。每次改 就是改 和 ,用 multiset 维护最小值即可。
做完了,时间复杂度 。
submission.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步