CF1270H

CF1270H

给出一个序列 \(a\),若对于 \(i<j\)\(a_i<a_j\) 则连一条 \(i\to j\) 的边,求联通块个数。

支持单点修改,保证任意时刻 \(a\) 互不相等。

  • \(n,q \le 5\times 10^5,a_i\le 10^6\)

\(\rm Sol:\)

先做一点观察,我们发现,连通块一定是一个区间。

对于 \((i,j)\) 假设两者之间有边,那么显然中间的点都与两者有边。

于是问题等价于存在分界点,等价于分界点的数量 \(+1\)

分界点的判定条件为不存在边跨过他,即左边最大值小于右边最小值。

接下来又来一个很神的转换,考虑枚举权值,对于 \(w\),将小于 \(w\) 的权值置为 \(0\),大于 \(w\) 的权值置为 \(1\),那么最后其可以得到一个分界点,其合法等价于序列会构成 111000...

方便起见,设 \(a_0=\infty,a_{n+1}=0\),考虑对于每个 \(w\),我们维护其是否在序列中出现,以 \(w\) 为视角进行观察,序列中的 10 数量,容易发现至少有一对 10,且 10 数量恰好为 \(1\)\(w\) 就是我们所求,考虑通过线段树维护,当一次修改将 \(a_i\) 改为 \(x\) 之后,我们将步骤拆开,视为将 \(a_i\) 改为 \(0\),再改为 \(x\),对于 \(w\in [a_{i+1},a_i]\)\(w\),本次修改会减少一组 10,而对于 \(w\in [a_i,a_{i-1}]\)\(w\),本次修改亦减少一组 10,注意到线段树直接维护难以处理区间修改的标记下传,但是注意到不存在 \(0\)10,所以我们直接维护最小值且存在的出现次数即可。

posted @ 2020-09-12 12:00  Soulist  阅读(153)  评论(0编辑  收藏  举报