ABC472 F - Centroid of a Slice

切断部の重心

考え方

物理学の重心の問題。
公式としては、以下のようになる。
ただし、$\rho$ は面密度。

$$
g_x = \dfrac{\iint \rho x \ \mathrm{d}x\mathrm{d}y}{\iint \rho \ \mathrm{d}x\mathrm{d}y}, g_y = \dfrac{\iint \rho y \ \mathrm{d}x\mathrm{d}y}{\iint \rho \ \mathrm{d}x\mathrm{d}y}
$$

とはいえ、さすがに積分の計算などやっていられないので、うまく対応することを考える。

この値は、領域が三角形で密度 $\rho$ が一定だった場合、分子分母それぞれ簡単に計算できる。
すなわち、$\triangle\mathrm{ABC}$ の符号付き面積を $S$ とすると、以下のようになる。

$$
\begin{aligned}
\text{分母} &= \rho S = \rho\overrightarrow{\mathrm{AB}}\times\overrightarrow{\mathrm{AC}}/2 \\
g_x\text{ の分子} &= (\mathrm{A}_x+\mathrm{B}_x+\mathrm{C}_x)\rho S/3 \\
g_y\text{ の分子} &= (\mathrm{A}_y+\mathrm{B}_y+\mathrm{C}_y)\rho S/3
\end{aligned}
$$

さらに、複数の物体の合体の場合、この積分値を分子分母それぞれ(約分せずに)足した値にすればよい。
切り落としの場合は同様に引けばよい。
ということは、多角形を大量の三角形に分割し、上記の公式と合体による総和で積分は回避可能。

0-indexed で、$\mathrm{P}$ の $i$ 番目の頂点を $\mathrm{A}_i$ と書くことにする。
$i=1,2,\dots,N-1$ に対し、$\triangle\mathrm{A}_{N-1}\mathrm{A}_{i-1}\mathrm{A}_i$ を求めておく。
($i=N-1$ の場合は明らかに $0$ だが)

まず、$u<v$ である場合。(これらも 0-indexed に直してあるとする)
この場合、まず $\triangle\mathrm{A}_{N-1}\mathrm{A}_{u}\mathrm{A}_{u+1},\triangle\mathrm{A}_{N-1}\mathrm{A}_{u+1}\mathrm{A}_{u+2},\dots\triangle\mathrm{A}_{N-1}\mathrm{A}_{v-1}\mathrm{A}_{v}$ を合体する。
そこにさらに $\triangle\mathrm{A}_{N-1}\mathrm{A}_{v}\mathrm{A}_{u}$ を合体すればよい。
最後の三角形は符号付き面積が負(または $0$)になるため、実質引き算である。
これを用いて分子と分母をそれぞれ計算し、割り算をすればよい。

$u>v$ である場合は、同じ計算をすると、扱いたい図形の逆側が負符号で出てくる。
よって、そこに図形全体の値を加算することで、意図した値となる。

……というのを累積和で処理することによって、$O(N)$ の事前処理のもと、各クエリが $O(1)$ で解ける。
よって、計算量は $O(N+Q)$ となる。

なお、小数を扱うのは望ましくないため、分母は $2$ 倍、分子は $6$ 倍した値で扱うとよい。
すべて整数で扱え、しかも long long 型の範囲から溢れることも起こらない。
また、$\rho$ の値はどうせ最終的に約分で消えるだけの値なので、$1$ としてしまってよい。

入力例1での動作

入力を受け取る。

n: 5
q: 4
p:
(4, 1)
(1, 3)
(-3, 2)
(-1, -2)
(2, -1)
queries:
(2, 4)
(5, 3)
(1, 4)
(4, 2)

頂点は 0-indexed で $\mathrm{A}_0=(4,1)$, $\mathrm{A}_1=(1,3)$, $\mathrm{A}_2=(-3,2)$, $\mathrm{A}_3=(-1,-2)$, $\mathrm{A}_4=(2,-1)$ である。

$\mathrm{A}_4$ を基準に、$\triangle\mathrm{A}_4\mathrm{A}_{i-1}\mathrm{A}_i$ を順に足していく。
各三角形について、分母の $2$ 倍と、$g_x,g_y$ の分子の $6$ 倍を求め、それぞれ累積和を取る。
$g_x,g_y$ の分子の $6$ 倍は、以下では $(x,y)$ の組で表す。

$i$ 分母の $2$ 倍 分子の $6$ 倍 $(x,y)$ 分母の $2$ 倍の累積 分子の $6$ 倍の累積 $(x,y)$
$1$ $10$ $(70,30)$ $10$ $(70,30)$
$2$ $17$ $(0,68)$ $27$ $(70,98)$
$3$ $14$ $(-28,-14)$ $41$ $(42,84)$
$4$ $0$ $(0,0)$ $41$ $(42,84)$

まず、最初のクエリ 2 4 を考える。
0-indexed では $u=1,v=3$ である。
累積和の差を取ると、$\triangle\mathrm{A}_4\mathrm{A}_1\mathrm{A}_2$ と $\triangle\mathrm{A}_4\mathrm{A}_2\mathrm{A}_3$ の合計が求まる。
この時点では、分母の $2$ 倍は $17+14=31$、分子の $6$ 倍は $(0,68)+(-28,-14)=(-28,54)$ である。

さらに $\triangle\mathrm{A}_4\mathrm{A}_3\mathrm{A}_1$ を加える。
この三角形の符号付きの分母の $2$ 倍は $-13$、分子の $6$ 倍は $(-26,0)$ なので、以下のようになる。

したがって重心は $(-54,54)/(3\times18)=(-1,1)$ である。

次に、$2$ つめのクエリ 5 3 を考える。
0-indexed では $u=4,v=2$ で、$u>v$ となる。
先ほどと同じように累積和の差を取り、両端を直接つなぐ三角形も加える。
このクエリでは $u=4$、つまり $\mathrm{A}_u=\mathrm{A}_4$ が基準点そのものなので、補正用の三角形は面積 $0$ である。
その結果、分母の $2$ 倍は $-14$、分子の $6$ 倍は $(28,14)$ となる。
これは求めたい領域ではなく、その逆側の領域を負符号で求めた値である。

そこで、多角形全体の値である、分母の $2$ 倍 $41$、分子の $6$ 倍 $(42,84)$ を加える。
すると、以下のようになる。

したがって重心は $(70,98)/(3\times27)=(70/81,98/81)$ であり、これが入力例1の $2$ つめの答えである。

注意点

三角形の符号付き面積の $2$ 倍や、それに座標を掛けて累積する値は、int 型からはみ出る場合がある。
long long 型を用いること。

別解

特になし。