Codeforces Round 1075

A. Table with Numbers

$a$ 以下と $b$ 以下をマッチングできるという形です.

好きな $x$ を選び,マッチ可能なものがあるならばそのうち最大のものとマッチ.という貪欲でよいです.

B. The Curse of the Frog

目標は $x$ 以上への到達だと思ってよいです.

$b_i-1$ 回ずつ進んだあと,戻る回数 $1$ 回あたりに進める距離が一番大きいもの一種類を貪欲に使っていきます.

C2. XOR-convenience (Hard Version)

C1:末尾に $1$ を置いて,$p[i]\oplus i=1$ を狙いに行くと上手くいきます.

  • $N=9$:$[8,3,2,5,4,7,6,9,1]$
  • $N=10$:$[10,3,2,5,4,7,6,9,8,1]$

C2:実験すると $N=2^k$ で No っぽいので理由を考えると,どこに $N$ を置いても上手くいかないことが分かります.

$N$ が奇数のときは,C1 のままで $i=1$ も大丈夫です.

$N$ が偶数のときも,C1 の微小変更で ok です.$a[1]$ と $a[i]$ のスワップというアイデアから,

$$a[1]=N,a[2^k]=2^k+1,a[N]=1$$

こうなっているのを

$$a[1]=2^k+1,a[2^k+1]=N,a[N]=1$$

これに取り換えることを考えます.$k$ を $N$ の lowest bit などととれば,上手くいきます.

D2. Little String (Hard Version)

まず D1 からですが,$[0]$ からはじめて,$1,2,3,\ldots$ を挿入していきます.

$x$ が mex として現れてもよいときには既存の列の両端に挿入($2$ 通り),そうでないときは $i$ 通りあるという雰囲気になります.D1 はこれを $c,10^9+7$ を法として計算すればよいです.

D2 です.? のところは $i$ 倍と $2$ 倍を選ぶという形になっていて,「$c$ の倍数になって欲しくない」「$f(w)$ が大きくなって欲しくない」という要請があります.

$i=1$ および $i$ が偶数のところでは,この両方の要請に共通の貪欲な選択肢を固定できるというのがポイントです.偶数のところを計算した時点での暫定的な $x=f(w)$ があります.

$x$ が $c$ の倍数になっていたら詰みです(ANS=-1).

この状態に,いくつかの奇数 $i(\geq 3)$ について,$2$ 倍または $i$ 倍を選べるということになっていて,目標は $c$ の倍数を回避することです.まずは全部 $2$ 倍を選んでみましょう.これで上手くいくならば,それが解です.

そうでないとき,$2$ 倍を選べる個数の上限があります.その上限を満たす限り,奇数はいくら選んでもよいです(全部 $2$ 倍を選ぶと $c$ の倍数になることから,奇数の素因数は $x$ の時点で $c$ と同数以上に入っているので,奇数を選んでも損しない).よって,大きな $i$ から貪欲に上限いっぱいまで $2$ に置き換えればよいです.

E. Majority Wins?

まず,コストは「列の長さの変化量から $1$ を引いたもの」です.列の長さを $N-1$ 減らす必要があるので,コストの和は「$N-1$ に操作回数を足したもの」となります.結局操作回数最小化が求めることです.

自明必要条件として,初期状態に 1 が必要です.さらにこれは十分条件にもなっています.01, 10 などが 1 にできるため.

重要観察として,いつでも $4$ 回以下の操作で条件達成できます.$1$ の左側全体,右側全体を $1,2$ 回目の操作とすればよいです.結局,$3$ 回以下でできるか判定する問題です.

$0$ 回は簡単.$1$ 回も簡単.

$2$ 回を考えます.初期状態の $0,1$ の個数を $a,b$ とします.$a\leq b$ なら $1$ 回でできています.$a\leq b+1$ なら $2$ 回でできています.これは $01$ を $1$ にすることを考えるとよいです.何かを $1$ にする操作では $b-a$ は $1$ までしか増加しないので,$1$ にする操作はこれで調べ終わりです.$0$ にする操作は区間和最大値を調べる感じに帰着されてできます.

$1…, 01…, …1, …10, …11…$ などは全部 $3$ 回以下でできることが分かります.

これ以外,というのは

  • 左端も右端も 00
  • 1 は隣接しない

というもので,これは $4$ 回かかることが示せます.$1$ 回操作したあとに,「両端は 0,片方の端は 00,1 が隣接しない」が残ることから示せます.

F. Zhora the Vacuum Cleaner

未証明AC.

ある点を連打するパターンだけ調べると AC になりました.この前提で,連打する点を根とする根付き木にします.操作回数 $t$ の場合の答を求めたいとします.

根以外の $v$ について,$subtree(v)$ 内の石の総数は $0$ 個になるまでひとつずつ減ります.このことから,各 $v$ について,時刻 $t$ での石の個数 $f_v(t)$ が計算できます.

だいたい $f_v(t)=\max(s_v-t,0)-\sum_w\max(s_w-t,0)$ の形です.$s$ が subtree での $a_v$ の総和で,$w$ は子をわたる和です.

これは $[0,s_v]$ で上凸になります.この範囲で,一次式から下凸を引いていく形になっているので.よって,正となる $t$ 全体は区間です.

根 $r$ を固定すると,各 $v$ に対して石がある時刻区間を求めて,これを区間加算してやることで $cost(t)$ が扱えて,その min を出力ということになります.

根を動かします.上の「区間」は,有向辺に対して定まります.よって根の変更ごとに,ひとつしか変わりません.次のような方針でよいです.

  • 各有向辺について「区間」を求める.
  • 区間の端点となる時刻で座圧する.
  • 木を dfs しながら,その点が根であるときの答を求める.dfs で通った辺の向きを反転するという処理になる.ある有向辺に対応する区間に $-q$ して,逆の有向辺に対応する区間に $+q$ するという処理になる.遅延セグメント木など.

各有向辺で「区間」を求めるときは,上述の通り上凸関数が正になる区間を求めるということなので,最大値を求めてから二分探索で前後に伸ばせばよいです.各頂点から出る辺をまとめて計算すると,全体で $O(N\log N\log(NA))$ のような計算量で解けます.

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