2019年8月5日月曜日

ABC 136 F - Enclosed Points

ABC 136 F - Enclosed Points

各点iSi \in Sについて、iiが何回数えられるかを求めればよいので、包除を考えるのがよさそう。点iiの上下左右の領域にある点の集合L,R,D,USL, R, D, U \in Sを定める:

L(i):={(x,y)Sx<xi}R(i):={(x,y)Sxi<x}D(i):={(x,y)Sy<yi}U(i):={(x,y)Syi<y}L(i) := \{(x, y) \in S| x<x_i\} \\ R(i) := \{(x, y) \in S| x_i < x\} \\ D(i) := \{(x, y) \in S | y<y_i\} \\ U(i) := \{(x, y) \in S| y_i < y\}

iiを含むSSの部分集合の総数は

2N2L(i)2R(i)2D(i)2U(i)+2L(i)U(i)+2L(i)D(i)+2R(i)U(i)+2R(i)D(i)12^N - 2^{|L(i)|}-2^{|R(i)|}-2^{|D(i)|}-2^{|U(i)|} \\ +2^{|L(i) \cap U(i)|}+2^{|L(i) \cap D(i)|}+2^{|R(i) \cap U(i)|}+2^{|R(i) \cap D(i)|}-1

で求まるので、これをiSi \in Sについて足し合わせればよい。1

さて、L(i),R(i),D(i),U(i)|L(i)|, |R(i)|, |D(i)|, |U(i)|は点をxx座標やyy座標についてソートしておけば尺取り法や二分探索等でそれぞれ求まる……が、よく見るとxixj,yiyj(ij)x_i \neq x_j, y_i \neq y_j (i \neq j)という条件があるので、単に整数0,1,...,N10, 1, ..., N-1が1回ずつ現れるだけであった。したがって、

iS(2N12L(i)2R(i)2D(i)2U(i))=N(2N1)4(20+21+...+2N1)=(N4)(2N1)\begin{aligned} & \sum_{i \in S}\bigl(2^N-1 - 2^{|L(i)|}-2^{|R(i)|}-2^{|D(i)|}-2^{|U(i)|} \bigr) \\ & = N \cdot (2^N-1) - 4 \cdot (2^0 + 2^1 + ... + 2^{N-1}) \\ & = (N-4)(2^N-1) \end{aligned}

である。

次にL(i)D(i),L(i)U(i),R(i)D(i),R(i)U(i)|L(i) \cap D(i)|, |L(i) \cap U(i)|, |R(i) \cap D(i)|, |R(i) \cap U(i)|を求める。(xi,yi)i{1,...,N}(x_i, y_i)_{i \in \{1, ..., N\}}xx座標についてソート済み(x1x2...xNx_1 \le x_2 \le ... \le x_N)とする。順序付きの集合OOを用意して、y1,y2,...,yNy_1, y_2, ..., y_Nの順にOOに入れていく時、点iiを処理した時点でOOの中のyiy_i未満の点の総数はL(i)D(i)|L(i) \cap D(i)|に等しく、yiy_iより大きい点の総数はL(i)U(i)|L(i) \cap U(i)|に等しい。同様のことを逆順yN,yN1,...,y1y_N, y_{N-1}, ..., y_1でやればR(i)D(i),R(i)U(i)|R(i) \cap D(i)|, |R(i) \cap U(i)|が求まる。


2Dのクエリを処理できるデータ構造があればテクニックが無くてもできそう。2Dセグメント木とかウェーブレット行列とかいろいろあるようだが、このスライドを眺めていて、とりあえずrange treeがすぐに書けそうに見えたので書いた。かなり重いが一応通った。

fractional cascadingでオーダーを落とすやつも書いた


  1. 最後の1-1は空集合を除いている。 ↩︎