Codeforces Round 559

A. The Party and Sweets

$a, b$ ともに昇順ソートしておきます.$a_n\leq x_{n,1}\leq b_1$ より $a_n\leq b_1$ が必要です.必要条件のもと目的が達成可能です.

$x_{ij}=a_i$ としたあと,列の最大値を増やさなければいけません.$a_n=b_1$ ならばすべて $x_{n,j}=b_j$ とするのが明らかに最適.そうでなければ $m-1$ 列を $n$ 行目からとって残りひとつを $n-1$ 行目からとります.

B. The minimal unique substring

000100010001… のような周期文字列で,最も左の 1 と最も右の 1 を含む部分文字列の長さが $k$ になるように調整すれば条件を満たします.

C. Permutation recovery

$p_i<p_j$, $p_i>p_k$ ($i<k<j$) というタイプの条件があります.この条件が成り立つときに $j\to i, i\to k$ と辺を張ってグラフを作り,toposort を求めればよいです.

グラフは辺の個数が多くなりますが,「ある頂点を使用済に変更する」「ある頂点から出ている辺で行先が未使用の点をひとつ求める」の 2 種の操作が適当なデータ構造で行えます.これらができるとグラフの toposort も求められます.

D. Winding polygonal line

常に凸包上の点に居る状態を保つようにして,$i$ 回目の移動が終わった時点で $i+1$ 回目の移動で左右どちらに曲がるかを確定している(つまり残っている点のどれを選んでも自動的に正しい方向に曲がれる)状態にします.

これを実現するのは,$i+1$ 回目で指示された方向を見て凸包上のどちらの境界に進むかを決めるようにすればよいです.毎回凸包を作らずとも,最も左,右に曲がるような次の点に進むという形で計算できます.

E. Strange device

適当な根をとって根付き木にします.$40$ 回程度で各頂点の深さを決定し,$30$ 回程度で各頂点の親を決定します.

まず深さの決定です.$v$ の深さを $d_v$ とします.$d_v$ を $2$ 進法で上の桁から決めていきます.

状態 $k$:$\lfloor d_v/2^k\rfloor$ がすべて求まっている.また深さが $2^k$ の倍数であるような頂点はすべて求まっている.

$k=10$ から初めて状態 $0$ までもっていきます.$4$ 回で $k$ をデクリメントできればよいです.

$\lfloor d_v/2^k\rfloor$ が奇数であるような $v$ 全体,偶数であるような $v$ 全体に分けてそれぞれ $2$ 回ずつのクエリで処理します.$2$ 回のクエリでは $x=2^{k-1}, x=2^{k-1}-1$ に対して深さが $2^k$ の倍数であるような点全体から距離が $x$ 以内にある点をクエリします.偶数奇数を分けているおかげで,クエリの結果は $d_v\bmod 2^k$ と $2^{k-1}$ の大小関係から決まり,状態 $k-1$ を得ることができます.

次に親の決定です.$k=0,1,2$ に対して $V_k$ を,深さを $3$ で割った余りが $k$ であるような頂点全体とします.$k=0,1,2$ に対してそれぞれ $10$ 回のクエリで $V_k$ の点の親を求めます.

クエリは $S\subset V_{k-1}$ を選び,$v\in S$ に対して $d_v=1$ とする形のクエリを投げます.深さを $\bmod 3$ で分類しているおかげで,$V_k$ の点に対するクエリの結果は親が $S$ に含まれるかだけで決まります.$i$ 回目の $S$ を $i$-th bit で決めるよくあるテクニックで,$V_k$ の頂点の親を決定できます.

F. Density of subarrays

$N^3$ みたいなのしかわからないと思って解説を見て解いたのだが,それに近いすごい計算量を主張している.試しに定数倍を丁寧に実装してみたら $\Theta(N^3)$ でも AC になってしまいました.

まず列の density というのは,列の先頭から見て「全種類の要素が現れる subarray」を貪欲にとっていったときにいくつとれるかによって定まります.

そこで,まず各 $i,j$ について 「$a_i,\ldots,a_{j}$ の部分列であって,$a_j$ が選ばれていて,そこではじめて全種類の要素が現れるものはいくつありますか?」を計算します.これは $a_i, \ldots, a_j$ における頻度集計だけから計算できて,特に $i$ を固定して計算することで $O(n^2)$ 時間程度で計算できます.

ここまでできれば答えを求める $O(N^3)$ 時間の dp を書くのは簡単です.

想定解法では $c$ が大きいならば density の最大値が小さいことを使って計算量を落とし,$c$ が小さい場合には bit dp のような別解を使い分けているようです.

CodeForces
スポンサーリンク
シェアする
maspyをフォローする
maspyのHP
タイトルとURLをコピーしました