目次
AtCoder Beginner Contest 478 E,F,G問題メモ
E - lt and le
問題文
- $1$ 以上 $N$ 以下の整数からなる長さ $N$ の整数列 $A$ であって、次の $Q$ 個の条件をすべて満たすものが存在するか判定し、存在する場合 $1$ つ求めてください。
- $i$ 番目 $(1\le i\le Q)$ の条件は整数の $3$ つ組 $(t _ i,u _ i,v _ i)$ で与えられ、以下のように定義されます。
- $t _ i=0$ のとき、$A _ {u _ i}\le A _ {v _ i}$
- $t _ i=1$ のとき、$A _ {u _ i}\lt A _ {v _ i}$
- すべての条件を満たす列が複数存在するときは、どれを出力しても構いません。
制約
- $1\le N\le2\times10 ^ 5$
- $1\le Q\le2\times10 ^ 5$
- $t _ i\in\lbrace0,1\rbrace\ (1\le i\le Q)$
- $1\le u _ i\le N\ (1\le i\le Q)$
- $1\le v _ i\le N\ (1\le i\le Q)$
- 入力はすべて整数
解法
$t_i=0$ と $1$ の違いは、イコールを許すか許さないか。
$u_i→v_i$ に辺を張ったグラフを考え、上流の頂点ほど小さい値を割り当てる、的なことを考えたい。 だが、ループが発生していると困りそう。
ループが $t_i=0$ だけからなるなら、全てに同じ値を割り当てればよいのでセーフ。
$t_i=1$ が絡むと不可能となる。よって、
- $t_i=0$ のみで辺を張り、強連結成分分解する。
- 同じ成分に入った頂点群は、同じ値を割り当てることが確定する。
- 強連結成分を縮約する。(1成分を1頂点とする)
- 縮約後のグラフに $t_i=1$ の辺を追加する。
- ただし、両端が同じ強連結成分に属する場合は、その時点で不可能が確定する。
- 再度、強連結成分分解し、複数個の頂点からなる強連結成分ができたら不可能が確定。
- そうでなければ、上流から小さい値を割り当てて完成。
F - Min-First Search
問題文
- 頂点 $1,$ 頂点 $2,\ldots,$ 頂点 $N$ からなる $N$ 頂点の木 $T$ に対して、以下の手順で得られる $(1,2,\ldots,N)$ の順列 $P$ を $f(T)$ とします。
- はじめ、列 $P$ を空列 $()$ とし、集合 $S$ を $\lbrace1\rbrace$ とする。
- 以下を $N$ 回繰り返す。
- $S$ の最小値を $x$ とする。$S$ から $x$ を削除し、$P$ の末尾に $x$を追加する。
- その後、$T$ において頂点 $x$ に隣接する頂点を頂点 $v _ 1,$ 頂点 $v _ 2,\ldots,$ 頂点 $v _ k$ とする。$i=1,2,\ldots,k$ について、$P$ に $v _ i$ が含まれていなければ $S$ に $v _ i$ を追加する。
- $(1,2,\ldots,N)$ の順列 $Q=(Q _ 1,Q _ 2,\ldots,Q _ N)$ が与えられます。$f(T)=Q$ となる木 $T$ の個数を $998244353$ で割った余りを求めてください。
- ただし、ふたつの木は、ある頂点の組 $(u,v)$ が存在して、一方の木では頂点 $u$ と頂点 $v$ の間に辺があり、もう一方の木では辺がないとき、区別されます。
制約
- $1\le N\le2\times10 ^ 5$
- $1\le Q _ i\le N\ (1\le i\le N)$
- $Q _ i\ne Q _ j\ (1\le i\lt j\le N)$
- $Q _ 1=1$
- 入力はすべて整数
解法
数ヶ月前のARCに、似たような考察をする問題があったような。
頂点 $1$ を根とし、$v$ の親を $p_v$ とする。
各 $v$ は、$p_v$ が $S$ の最小値となって取り出され、$P$ に追加されたときに、$S$ に追加される。
つまり、$Q$ において、$v$ の親は $v$ より先に出現している。
頂点 $1$ のみがあり、そこに $Q_2,Q_3,...$ の順に頂点、およびその頂点と親を結ぶ辺を追加していくことを考える。
前述の考察より、$v$ を追加するとき、$p_v$ は(どれにするかは自由度があるが、どれにするにしろ)既に木に追加されている。
途中経過の一例
① Q: 1 16 23 14 [18] ...
/|↖
⑯ ㉓ ?
/↖ ↖
⑭ ? ?
↖
?
ある頂点を追加するとき、既存の頂点のどれなら親にして問題ないか?
これは、「その頂点から遡って、初めて出てくる、自身より大きい頂点まで」(その次からアウト)となる。
上例では⑱を追加するのに、⑭と㉓はOKで、①と⑯はアウトとなる。
元の操作を考えたとき、親が $P$ に追加された時点で $S$ には⑱が追加されるため、
㉓と同時または先に $S$ に入ってしまうと、⑱より先に㉓が取り出されるのが矛盾する。
⑱は $S$ に入るのは、㉓が取り出された後でないといけないからである。
⑱は2通りの接続先があることになる。
接続先の個数は、木の構造がどうであるかは関係なく、$Q$ のみによって決まる。
よって、各 $i$ につき、「$L_i:=Q_i$ より遡って最初に出現する $Q_i$ より大きい値のindex、存在しない場合は $1$」とすると、
- $\displaystyle \prod_{i=2}^{N}(i-L_i)$
が答えとなる。$L_i$ は、セグ木に載せて min_left を使ったり、Editorialにある方法を使ったりすると求められる。
G - Division Point Hull
問題文
- 座標平面上に $N$ 個の点 $P_1,P_2,\dots,P_N$ があります。点 $P_i$ の座標は $(X_i,Y_i)$ です。
- 正整数 $p,q$ が与えられます。線分 $P_iP_j$ を $p:q$ に内分する点を $Q_{i,j}$ とします。特に $P_i=P_j$ ならば $Q_{i,j}=P_i$ です。
- $1 \leq i \lt j \leq N$ を満たすすべての正整数組 $(i,j)$ に対する $Q_{i,j}$ についての凸包の面積を求めてください。
制約
- $2 \leq N \leq 10^5$
- $1 \leq p \lt q \leq 10$
- $|X_i|\leq 10^7$
- $|Y_i|\leq 10^7$
- 入力はすべて整数
解法
分割統治。
- 点集合 $S$ の凸包を $\operatorname{Conv}(S)$ とする。
- $P[l:r]$ を、$P_l,P_{l+1},...,P_{r-1}$ の点集合とする。
- $Q[l:r]$ を、$P$ の任意の2点間の内分点からなる点集合とする。
$\operatorname{Conv}(Q[0:N])$ を求めたい。
分割統治を考えた場合、$l,r;(l \lt r)$ に対し、$m=(l+r)/2$ として
- $R[l:m:r]=\{(x_1+x_2,y_1+y_2) | (x_1,y_1) \in S, (x_2,y_2) \in T\}$
- $S=\{(\frac{q}{p+q}x,\frac{q}{p+q}y) | (x,y) \in P[l:m]\}$
- $T=\{(\frac{p}{p+q}x,\frac{p}{p+q}y) | (x,y) \in P[m:r]\}$
- 平たく言うと、$P[l:m]$ と $P[m:r]$ から1点ずつ選んで内分した点の集合
- $Q[l:r]=Q[l:m] \cup Q[m:r] \cup R[l:m:r]$ …①
が成り立つ。これを求めやすい形にしていく。
まず、基本的な定理として、一般の点集合について以下が成り立つ。
- $\operatorname{Conv}(S \cup T)=\operatorname{Conv}(\operatorname{Conv}(S) \cup \operatorname{Conv}(T))$
つまり、$S \cup T$ で凸包の頂点となり得る点は、 $S,T$ それぞれで凸包を取った時にいずれかの頂点となってる点に限られる、ということ。
これを①に適用して、以下が成り立つ。
- $\operatorname{Conv}(Q[l:r])=\operatorname{Conv}(\operatorname{Conv}(Q[l:m]) \cup \operatorname{Conv}(Q[m:r]) \cup \operatorname{Conv}(R[l:m:r]))$
$\operatorname{Conv}(R[l:m:r])$ を求める部分以外の計算量は $r-l$ に比例する。 問題は $\operatorname{Conv}(R[l:m:r])$ を求める部分で、愚直には $[l,m) \times [m,r)$ だけの点から凸包を求めるので $O(N^2)$ かかる。
ここで、以下の事実がある。
- $\operatorname{Conv}(R[l:m:r])$ は、$\operatorname{Conv}(P[l:m])$ と $\operatorname{Conv}(P[m:r])$ から、$O(r-l)$ で求められる
予め $S=\frac{q}{p+q}P[l:m]$、$T=\frac{p}{p+q}P[m:r]$ としておく。 こうすると、$R[l:m:r]=\{s+t|s \in S,t \in T\}$ より、 単純な足し算( Minkowski和)で、内分点より考えやすくなる。
$\operatorname{Conv}(R)$ が示す図形に、無限遠からある傾きの直線を近づけていって、最初にぶつかる頂点を考える。 (辺と平行なら2点あり得るが、ひとまず1点とする)
この頂点は、$S,T$ からどの点とどの点を選んで和を取ったものか?
これは、同じ傾きの直線を $\operatorname{Conv}(S),\operatorname{Conv}(T)$ それぞれに近づけていって、
最初にぶつかる頂点同士を選んで和を取ったものとなるはずである。
よって、近づける直線の傾きを少しずつ変えて1周させれば、$\operatorname{Conv}(R)$ の全ての頂点が明らかになる。具体的には、
- $\operatorname{Conv}(S)$ の頂点で $(x,y)$ が最小の点を $s_0$ とし、反時計回りに $s_1,s_2,...$ となるように配置する。$T$ も同様。
- $i=j=0$ で初期化し、以下を繰り返す。
- $s_i+t_j$ を $R$ に加える
- $s_i→s_{i+1}$ と $t_j→t_{j+1}$ の偏角が小さい方のポインタを $1$ 進める(同じなら両方)
ということを繰り返すと、$R$ を $O(|\operatorname{Conv}(S)|+|\operatorname{Conv}(T)|)$ で構成できる。
よって、$\operatorname{Conv}(Q[l:r])$ が $O(r-l)$ で求められ、分割統治全体で $O(N \log{N})$ で求められる。
上記の議論は、上側凸包同士・下側凸包同士を別々に考えても成り立つ。
実装上は、上側凸包・下側凸包に分けて構成した方が、偏角が $\infty,-\infty$ をまたぐ部分などで混乱せず楽かも。

