cf1540d-solution
CF1540D Solution
题意:
给你一个长度为 的序列 ,支持以下操作:
1 x y
:令 。
2 x
:构造 的排列 ,满足 , 恰有 个数大于 。求 。
为方便,将 ,这样 就是 中 的排名。
手玩一下构造。假设有 ,从 到 逐个构造 。
a : 1 2 2 1 3
p : 1
p : 1 2
p : 1 3 2
p : 2 4 3 1
p : 2 5 4 1 3
你发现每次构造 时就是将 ,将前面所有 的 全部 。
这里有重要性质:每次构造只会影响前面已构造的 ,不会影响到后面还没构造的 。
回到原题,题目每次要求 ,那么根据上面的性质,我们直接从 开始构造,并计算构造后面 时对 的影响。
那么询问转化为,初始 ,然后从 枚举到 ,如果 则 。
考虑序列分块,块长为 。我们尝试在每块内维护 表示数 从块左端点走到右端点会增加多少。
那么由于块长为 , 的值全部都 且单调不降。
即 可以被看做一个只有 种取值的分段函数,函数值分别为 。
我们直接维护块内的分段函数的 个自变量边界,询问暴力跳块用 upper_bound
询问函数值即可。
最后处理单点修改。考虑每块开线段树,线段树结点维护它对应区间的分段函数边界,push_up
直接线性归并即可。
这样单点修改复杂度是 的。
复杂度是 的,取 ,最终时间 ,空间 。
听说可以分散层叠 (?
upd:好像不用分散层叠也可以
具体地,把询问和修改塞到每个块中,离线从左到右逐块处理,
每个块的修改操作将询问分成若干段,每段内线段树根节点的形态是一样的。于是可以双指针直接扫。
注意双指针之前要把同一段中的询问按照它本来的 排序,这个排序用快排复杂度会退化,用计数排序即可。
还有为了做到线性空间,我们在塞询问时只把询问塞到最左边的块,然后处理完这个块把询问塞到下一个块中。
时间复杂度是 ,空间 。然而常数过大被带 log 的吊着踩。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】