固定 $i$ 计算所有 $(i,j)$ 的答案。求出 $P_i$ 与另外 $n-1$ 个点的中垂线 $L:=\{\ell_k \mid \text{bisect}(P_i,P_k)\}$。$L$ 会把平面划分成 $\mathcal{O}(n^2)$ 个区域,每个区域对应的 $j$ 都是唯一的,考虑计算出这个 $j$。
观察到每条直线会产生如下贡献:$\ell_k$ 把平面分成两半并且让靠近 $P_k$ 的一侧的 $j$ 加 $1$。根据这条观察导出如下算法:
- 维护一个凸包的集合 $S$,初始时 $S$ 仅包含地图矩形;
- 逐条加入直线 $\ell_k$,令 $S$ 中近 $P_k$ 侧的凸包的 $j$ 增加 $1$;
- 对于跨过直线的凸包,用 convex cut 分成两半并更新其中一半的 $j$;
- 加入所有直线之后,遍历 $S$ 中的凸包,将凸包的面积累加到 $(i,j)$ 的答案上。
时间复杂度毛估估是 $\mathcal{O}(n^4)$ 的,实际上把 $L$ shuffle 之后跑的飞快。
还有一个问题就是多次求交点(i.e., convex cut 的时候用凸包上的点和直线求交)有累计误差会爆炸。解决方案是记录下凸包上的边对应的是哪条直线 $\ell$,$\ell$ 能用两个整点表示出来(读入时把坐标 $\times 2$),然后用 $\ell$ 求交精度就是够的。