题意
平面直角坐标系上给定 \(n\) 个矩形,第 \(i\) 个矩形颜色为 \(i\),颜色大的矩形将覆盖颜色小的矩形,问最后能看到几种颜色。
\(1\le n\le 10^5,|x_i|,|y_i|\le 10^9\)
题解
首先离散化,考虑扫描线如何维护序列上的颜色。
一个区间 \([l,r]\) 投射到线段树上 \(O(\log n)\) 个不交区间,总共 \(O(n\log n)\) 个。对于每个区间,直接把每种颜色塞到一个 set 里,当前区间可能被看到的颜色只会是 set 最大值,记为 \(v_x\)。
考虑只插入怎么做,发现 \(i\) 处的颜色即线段树上根节点到 \([i,i]\) 路径上每个 \(v_x\) 取 \(\max\),那我在一个被颜色 \(c\) 完全覆盖的区间 \([l,r]\) 上,若根到 \([l,r]\) 路径上的 \(\max v_x\) 小于 \(c\),且存在该节点到某一叶节点的路径 \(\max v_x\) 也小于 \(c\),说明 \(c\) 可被看到,于是在线段树上维护 \(mn_x\) 表示所有 \(x\) 到叶节点的路径 \(\max v_x\) 的最小值,即可 \(O(1)\) 判断,每次最多增加 \(1\) 个新颜色。
现在加入删除操作,一个区间的删除可能会增加更多可被看到的颜色,但答案最多 \(O(n)\) 个,那我设法只考虑没被看过的颜色,用 \(mx_x\) 表示以 \(x\) 为根的子树,没被统计过且可能会被看见的最大颜色,从 \([l,r]\) 中删掉颜色 \(c\),重新计算 \(v_x\)。pushup 时先继承左右儿子,考虑 \(v_x\) 对 \(mn_x\) 和 \(mx_x\) 的贡献,分两种情况:
-
若 \(v_x\) 已被统计过,\(mn_x\gets\max(mn_x,v_x)\)。
-
若 \(v_x\) 未被统计过,\(mx_x\gets\max(mx_x,v_x)\)。
若 \(mn_x>mx_x\),即当前区间可能会被看见的最大颜色比 \([l,r]\) 中已被看见的最小颜色还小,越往上走 \(mn_x\) 只增不减,自然看不见 \(mx_x\) 了,令 \(mx_x\gets 0\)。
若 \(mx_1\ne 0\),说明出现了一种从未被看见的颜色被看到了,标记为已看见,并把 \(mx_1\) 对应的 \(O(\log n)\) 个区间拉出来修改信息。若修改后 \(mx_1\) 仍不为 \(0\),就继续修改,直到 \(mx_1=0\)。因为最多只有 \(n\) 个颜色,所以总修改次数最多 \(n\) 次。
线段树一个 \(\log\),set 一个 \(\log\),时间复杂度 \(O(n\log^2 n)\)。
标签:Arkady,颜色,log,题解,mn,max,区间,Rectangles,mx From: https://www.cnblogs.com/Terac/p/18038209