CF1270H
CF1270H
给出一个序列 a,若对于 i<j 有 ai<aj 则连一条 i→j 的边,求联通块个数。
支持单点修改,保证任意时刻 a 互不相等。
- n,q≤5×105,ai≤106
Sol:
先做一点观察,我们发现,连通块一定是一个区间。
对于 (i,j) 假设两者之间有边,那么显然中间的点都与两者有边。
于是问题等价于存在分界点,等价于分界点的数量 +1
分界点的判定条件为不存在边跨过他,即左边最大值小于右边最小值。
接下来又来一个很神的转换,考虑枚举权值,对于 w,将小于 w 的权值置为 0,大于 w 的权值置为 1,那么最后其可以得到一个分界点,其合法等价于序列会构成 111000...
方便起见,设 a0=∞,an+1=0,考虑对于每个 w,我们维护其是否在序列中出现,以 w 为视角进行观察,序列中的 10
数量,容易发现至少有一对 10
,且 10
数量恰好为 1 的 w 就是我们所求,考虑通过线段树维护,当一次修改将 ai 改为 x 之后,我们将步骤拆开,视为将 ai 改为 0,再改为 x,对于 w∈[ai+1,ai] 的 w,本次修改会减少一组 10
,而对于 w∈[ai,ai−1] 的 w,本次修改亦减少一组 10
,注意到线段树直接维护难以处理区间修改的标记下传,但是注意到不存在 0 对 10
,所以我们直接维护最小值且存在的出现次数即可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步