Description
二维坐标系上有 $n$ 条线段,每条线段连接 $(x_{i,1},y_{i,1}),(x_{i,2},y_{i,2})$ 两个整点,且所有线段平行于坐标轴,保证平行于同一条坐标轴的线段不相交。求这些线段能组成多少个矩形。
$(1 \leq n \leq 5 \times 10^3,x,y \in [-5 \times 10^3,5 \times 10^3])$
Source
Solution 1
暴力做法。先把横线和竖线分开存储,我们可以 $O(n^2)$ 预处理出与第 $i$ 条横线相交的竖线集合为 $f_i$ 。接下来枚举矩形的上下两条边为第 $i$ 条横线和第 $j$ 条横线,那么同时与这两条横线相交的竖线集合为 $f_i \cap f_j$,假设这个集合的大小为 $x$,则能形成 ${\rm C}_x^2$ 个矩形,累加就能得到答案。显然可以用 $\rm bitset$ 优化,时间复杂度为 $O(\frac{n^3}{w})$ 。但是这样写当横线数量大时会被卡掉,所以可以特判一下横线竖线哪个多,如果横线较多, 就反过来预处理横线集合,枚举竖线。
Code 1
1 |
|
Solution 2
考虑将横线按 $y$ 坐标从小到大排序,竖线按上端点的 $y$ 坐标从小到大排序。然后枚举矩形下面的边为第 $i$ 条横线,把所有与该横线相交的竖线存到队列里,用树状数组维护区间竖线数量。接着枚举矩形上面的边为第 $j$ 条横线(在第 $i$ 条横线的上方),对于队列里上端点在第 $j$ 条横线下方的竖线,我们可以在树状数组中把它删掉,因为它不与第 $j$ 条横线相交。由于队列里竖线的上端点单调递增,这步操作可以线性解决。对于每对 $i,j$,用树状数组查询区间竖线数量,统计答案。注意树状数组的下标不能为非正数,所以给所有初始坐标加上一个较大的整数,时间复杂度 $O(n^2 \log n)$ 。
Code 2
1 |
|