Codeforces Round 1102

A. Euclid, Sequence and Two Numbers

降順ソートが必要条件.十分であるかをチェック.

B. Palindrome, Twelve and Two Terms

例えば $(n\bmod 12)\leq 9$ ならば,$a=0,1,\ldots,9$ でよいです.

残りも $a=11, 22$ までチェックすればよいことが分かります.

D. XOR, Expression and Two Binary Numbers

$N$ ビットありますが,$4$ 種類しかありません.つまり,入力の $2$ つの列において,「$(0,0),(0,1),(1,0),(1,1)$ であるものの個数がいくつ」というようにできます.

操作して再帰的に小問題にしていく過程でも,これらの $4$ 種の個数が適当な順に置換されるだけです.したがって,「$k$ およびこれらの $4$ 種の個数」を状態として計算をすれば,$O(k)$ 状態しかないことが分かります.

E. Vlad, Misha and Two Arrays

Cartesian Tree を考えると,両方の部分木サイズに $1$ を加えたものの積が与えられているということになります.

bottom up に根付き木を作っていきます.

まだ根付き木としていない頂点の左右にある根付き木(または空)を見て,それらを $2$ つの子として個数がぴったりならば採用.とします.ぴったりなのに採用を遅延すると左右の木が育ってしまってしまうので,そのタイミングで採用してしまうしかありません.

これで可能な限りまとめていって,ひとつの根付き木になれば ok です.数え上げは左右の部分木サイズの二項係数をかければよいです.

F. Vessels, Heights and Two Versions (Hard Version)

円環を周期的に延長して列にしておきます.

$[i-N+1,i+N)$ 部分についてまず列だと思って計算します.すると,$i$ から左右方向に,累積 max をとった値が上限ということになります.円環で解くときは,これら $2$ 種の上限の min がそれぞれの場所での値となります.

これをすべての $i$ で求めます.長さ $3N$ の列を用意して,$i$ を走査.各時点で $[0,i)$ 部分および $[i+1,3N)$ 部分について,左方向,右方向の適切な累積 max が書き込まれた列を管理します.これは単調スタックを持って,区間定数代入の形で管理できます.(ある方向には,スタックのシミュレーションを逆順に行う形になるため事前に逆順に計算したものを巻き戻していくようにやります,ややこしい.)

あとは,「左回りの方が小さい範囲」「右回りの方が小さい範囲」を二分探索で境界を求めて区間和をとればよいです.

左回り,右回りでどこまで進むかの境界は単に全体の max の位置で,そうすると左右それぞれの計算を分離できて簡単だったみたいです.

G. Stripe, Token and Two Players

状態 $(p,i)$ を,power $p$, 座標 $i$ とします(結果的に p,i 順の方が実装しやすいと思います).

  • $A[p][i]$:$(p,i)$ で power 変更なしで出発した場合の勝敗
  • $B[p][i]$:$(p,i)$ で power 変更ありで出発した場合の勝敗

とします.これらを何らかの形ですべて求めるのが目標です.

重要なこととしては,$B[p][i]$ が負けであるような $(p,i)$ が $O(N\log N)$ 個しかないということです.

$B[p][i]$ が負けならば,$B[p][i-k]$($1\leq k\leq p$)は勝ちだからです.よって,これらを求めるという目標が立ちます.

以下,$p$ について降順に処理します.

補助的に,$nxt[i]$ として,「$A[p][i]$ が win であるような最小の $p$」というものも管理します.

$B$ が lose のところの計算方法

losing position を降順に探します.最後に見つけた losing position を $j$ とするとき,次の losing position $i$ は

  • $i < j – p$
  • $p + a[i] < nxt[i]$

を満たす中で最大のものです.したがって,$seg[i]=nxt[i]-a[i]$ という range max segtree を持っておけばこれを発見できます.

$A$ が win のところの計算方法

$B[p][-]$ がすべて求まったら,$b$ が losing position に対して区間 $[b-p,b-1]$ が $A$ の winning position になります.

$nxt[i], seg[i]$ の更新

$A$ の winning position 区間が求まったら,nxt[i] に区間代入が入ります.これは全体で $O(N\log N)$ 回の「区間定数加算」に言い換えることも可能なので,その形で処理すれば $seg[i] := nxt[i]-a[i]$ も区間加算遅延セグ木で処理できます.

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