−目次
AtCoder Regular Contest 192 (Div. 2) A,B,C,D,E問題メモ
A - ARC Arc
問題文
- 正整数 N と、長さ N の 0 または 1 からなる数列 A=(A1,A2,…,AN) が与えられます。
- 長さ N の英大文字のみからなる文字列 S であって、以下の操作を 0 回以上好きな回数行うことで A に 0 が含まれないようにできるものを 良い文字列 と呼びます。
- 次のうちどちらかを選び、実行する。
- 1≤i≤N なる整数 i であって Si= A、Si+1= R、Si+2= C となるものを選び、Ai,Ai+1 を 1 に置き換える。
- 1≤i≤N なる整数 i であって Si+2= A、Si+1= R、Si= C となるものを選び、Ai,Ai+1 を 1 に置き換える。
- ここで、Si (1≤i≤N) で S の i 文字目を表し、SN+1=S1,SN+2=S2,AN+1=A1 とします。
- 良い文字列が存在するか判定してください。
制約
- 3≤N≤200000
- Ai∈{0,1} (1≤i≤N)
- 入力はすべて整数
解法
ARCRARCRA… のように“ARC”と“CRA”を重ね合わせつつ繰り返せばほとんどの Ai は“1”に置き換えることができる。
特に、[ARCR…ARCR] のように最後の“A”の手前で切って最初に戻るものは、全て“1”にできる。
このようなことができるのは、N が 4 の倍数の時である。
4で割ったあまりで場合分けすることを考えると、1か3の場合は、
N%4 1 ARCR...ARCRA 1111...11110 ←操作により1にできる位置 3 ARCR...ARCRARC 1111...1111110 ←操作により1にできる位置
いずれも最後の位置だけ操作により“1”にすることができない。
逆に言うと、ここが初期状態で“1”だった場合は良い。
indexはループしていて任意の位置に合わせられるため、初期状態に“1”が1つでもあれば良い。
2余る場合が厄介。この場合、2箇所はどうしても“1”にできない。この位置に初期状態で“1”があるなら良い。
N%4 2 ARCR...ARCRAR 1111...111100
ただ、2つの“1”は連続している必要は無い。2つの「偶数個の“1”+“0”」に分け、この“0”の両方に初期状態を合わせられればよい。
ARCR...ARCARCR...ARCRA 1111...1101111...11110
この時、2つの“0”のindexの偶奇は異なっている。
初期状態で Ai=“1” である i を偶奇に分けた時、いずれにも1つ以上あれば良い。
B - Fennec VS. Snuke 2
問題文
- フェネックとすぬけくんがボードゲームで遊んでいます。
- 正整数 N と、長さ N の正整数列 A=(A1,A2,…,AN) が与えられます。また、集合 S があり、はじめ S は空集合です。
- フェネックとすぬけくんは、フェネックから順に次の一連の操作を交互に行います。
- 1≤Ai なる i を選ぶ。Ai から 1 を引き、i∉S ならば S に i を追加する。
- S={1,2,…,N} となっていたら、最後に操作したプレイヤーを勝者としてゲームを終了する。
- フェネックとすぬけくんは、どちらも自身が勝者になることを目指して最適な行動を行います。
- どちらが勝者になるか判定してください。
制約
- 1≤N≤2×105
- 1≤Ai≤109 (1≤i≤N)
- 入力はすべて整数
解法
実験したら、証明はともかく、法則性は簡単に推測できる。(また、ゴールが見えた方が証明もしやすい)
ただ、証明は場合分けが多くて大変。
とりあえず小さいケースでは、
- N=1 の時は明らかに「先手必勝」
- N=2 の時、S に一方を追加すると相手は即座にもう一方を追加すれば勝つ。「後手必勝」
- N=3 の時、
- A に2種類目の要素を追加したら、相手は即座に3種類目を追加するので負ける
- → なるべく2種類目の要素の追加を相手に押しつけたい
- → 先手が1種類目に追加した i を、Ai が0になるまで互いに選び続ける
- Ai=0 となり2種類目を追加せざるを得ないのは、Ai が奇数なら後手、偶数なら先手
- 先手は奇数の Ai があればそれを1種類目とすることで「先手必勝」。なければ「後手必勝」
N≥4 以降は分岐が多くなるので人力での全探索は難しい。(実際はここから実験に転換した)
ただし、小さいケースで分かったこともあって、「A で1以上の要素がラスト2になった状態」が重要そうである。
問題を以下のように言い換える。
一旦 S に追加した後の Ai はどれを選んでも変わらないので、X という1変数にまとめてしまえる。
- 数列 A={A1,...,AN} と、変数 X=0 を用意する。
- 各手番では2種類の操作のいずれかを選んで行う。
- A から1要素 Ai を選び、取り除く。Ai−1 を X に加算する。
- X を1減らす。(X>0 の場合のみ)
- A を空にする操作をした方が勝ち
A に残る要素が2、かつ X が偶数の状態で相手に手番を回せる方が勝つ。
X は、ひいてはその加算元となる各 Ai は、偶奇のみが重要と分かる。
更に以下のように言い換える。
- A にある奇数の要素数を Co、偶数の要素数を Ce とする。1bit変数 X=0 を用意する。
- 各手番では3種類の操作のいずれかを選んで行う。
- Co を1減らす。(Co≥1 の時のみ)
- Ce を1減らし、X を反転させる。(Ce≥1 の時のみ)
- X を1減らす。(X=1 の時のみ)
- Co=Ce=0 にする操作をした方が勝ち
初期状態を以下で場合分けする。ただし Co+Ce≥4 とする。
3つ組の意味を、(Coの偶奇,Ceの偶奇,X) とする。
また、偶4 のような表記は「4以上の偶数」を意味するとする。
- ① (偶,偶,0)
- ② (偶,奇,0)
- ②a) (0,奇5,0)
- ②b) (2,奇3,0)
- ②c) (偶4,奇,0)
- ③ (奇,偶,0)
- ④ (奇,奇,0)
- ④a) (1,奇3,0)
- ④b) (奇3,奇,0)
①は後手必勝である。後手は、先手と同じ操作をすれば先手に (偶,偶,0) を渡す状態をキープできる。
この状態はいつか (0,0,0) となり、後手を最後の手番として終了する。
また③は、先手が初手で Co を選べば①を後手に回せるので、先手必勝となる。
②④がややこしい。Co,Ce が少なくなると行動が変わる。
④は先手必勝となる。
- ④a) (1,奇3,0) の時、先手は Co を減らし、(0,奇3,0) を相手に渡す。
- 後手は Ce を操作するしかなく、(0,偶2,1) が返ってくるので、(0,偶2,0) を返せば①に帰着して先手必勝。
- ④b) (奇3,奇,0) の時、先手は Ce を減らし、(奇3,偶,1) を相手に渡す。
- 後手は、
- Co を減らすと (偶2,偶,1) なので次に先手は (偶2,偶,0) を渡せば①に帰着して先手必勝
- X を減らすと (奇3,偶,0) なので次に先手は (偶2,偶,0) を渡せば①に帰着して先手必勝
- Ce を(あるなら)減らすと (奇3,奇,0) となり④b)に戻る
後手は Ce を操作するしかないが、それが可能なのも Ce が尽きるまでなので、 なくなったら他のいずれかを操作せざるを得ず、すぐに必敗パターンに持ち込まれる。
②は、後手必勝となる。
- ②abc) 全てにおいて、
- 先手が初手 Ce を減らすと (偶,偶,1) を相手に渡すことになり、(偶,偶,0) が返ってきて負ける
- 先手は Co を操作するしかない。
- ②a) の場合、Ce しか操作できない。
- ②b) の場合、(1,奇3,0) を渡すことになるので④a)に帰着される。
- ②c) の場合、(奇3,奇,0) を渡すことになるので④b)に帰着される。
いずれでも後手必勝となる。
C - Range Sums 2
問題文
- この問題はインタラクティブな問題です。
- 正整数 N が与えられます。
- すぬけくんは、(1,2,…,N) を並び替えた正整数列 P=(P1,P2,…,PN) と、長さ N の正整数列 A=(A1,A2,…,AN) を隠し持っています。ここで、P1<P2 が保証されます。
- あなたは、すぬけくんに 2N 回までクエリを送ることができます。クエリは以下のようなものです。
- 1≤s,t≤N なる相異なる正整数 s,t を指定し、max(Ps,Pt)∑i=min(Ps,Pt)Ai の値を教えてもらう。
- P,A を特定してください。
制約
- 3≤N≤5000
- 1≤Pi≤N (1≤i≤N)
- Pi≠Pj (i≠j)
- P1<P2
- 1≤Ai≤109 (1≤i≤N)
- N,Pi,Ai は整数
- P,A はジャッジとの対話前に決定される
解法
Ai が正なので、(1,2),(1,3),...,(1,j),...,(1,N) をクエリで聞いたとき、 最も大きい値が返る j が Pj=1 または Pj=N となる。
i 1 2 3 4 5 6 i 1 2 3 4 5 6 P 2 4 6 5 3 1 A 1 9 2 25 2 9 クエリ (Pi,Pj) 返値 (1,2) → (2,4) [----] 36 (1,3) → (2,6) [--------] 47 ← j=3 の時最大 (1,4) → (2,5) [------] 38 ⇒P3 が1,Nのどちらか (1,5) → (2,3) [-] 11 (この例では N だが、 (1,6) → (2,1) [-] 10 この時点では回答側にとっては不明)
今度は j を主軸として (j,2),(j,3),...,(j,N) をクエリで聞くと、
返値の昇順が j から近い順となる。
また、差分を取っていけば、最初の2つ以外の Ai は分かる。
クエリ (Pi,Pj) 返値 (3,1) → (6,2) [--------] 47(←実際は上で聞いているので聞かなくていい) (3,2) → (6,4) [---] 36 (3,4) → (6,5) [-] 11 (3,5) → (6,3) [------] 38 (3,6) → (6,1) [----------] 48 i 3 4 2 5 1 6 P 1 2 3 4 5 6 (または 6 5 4 3 2 1) 返値 11 36 38 47 48 i 1 2 3 4 5 6 A [11] 25 2 9 1 ←返値の差分から計算
A1,A2 に関しては和しか分からないが、ここまでわかれば1回の追加クエリで判別できる。
ここまでで 2N−2 回のクエリなので間に合う。
最後に P を復元し、P1>P2 となっていたら反転すれば良い。
D - Fraction Line
問題文
- 正の有理数 x に対し、f(x) を以下のように定義します。
- x を互いに素な正整数 P,Q を用いて PQ と表したときの P×Q の値
- 正整数 N と、長さ N−1 の正整数列 A=(A1,A2,…,AN−1) が与えられます。
- 以下の条件をすべて満たす長さ N の正整数列 S=(S1,S2,…,SN) を 良い数列 と呼ぶことにします。
- 1≤i≤N−1 なるすべての整数 i について、f(SiSi+1)=Ai が成り立つ。
- gcd(S1,S2,…,SN)=1
- 数列の スコア を、その数列に含まれる要素の総積と定義します。
- 良い数列の個数は有限個であることが証明できます。良い数列すべてに対するスコアの総和を 998244353 で割った余りを求めてください。
制約
- 2≤N≤1000
- 1≤Ai≤1000 (1≤i≤N−1)
- 入力はすべて整数
解法
B,C問題と同じ配点とは思えない難度だが、得意な人は得意なのかも。
まず、サンプル1から良い数列の例を見る。
Si,Si+1 で隣り合う数の比が、Ai になっていればよさそう……?
A 1 9 2 2 9 S 2 2 18 9 18 2 x9 /2 x2 /9 ← Si から Si+1 にするための計算 S 18 18 2 1 2 18 /9 /2 x2 x9
ただ、これは A がいずれも単一の素因数しか持たないからで、合成数ならもう少し違ってくる。
A 6 15 20 S 2 3 5 100 /2 x4 x3 /3 x5 x5
全体として比が Ai になっていなくても、素因数毎の比の積が Ai になっていればよい。
実際、f(x) の定義を考えると、Si×a/b=Si+1 の時、f(SiSi+1)=ab となる。
ただし、a と b は互いに素でないといけないので、
たとえば Ai=22 の時、2を a にも b にも分けるということはできない。
要は Ai の素因数の種類毎に、1つ前の数に「かける」「わる」の2通りの選択肢があり、それ毎に異なる S ができる。
上例では、6,15,20 はいずれも 2131,3151,2251 と2種類ずつの素因数を持ち、計6個あるので、26 の S が存在する。
素因数毎に分解してスコアを考える。
- B(p):=A から素因数 p のみを取り出した数列。
- 例) A=(6,15,20) → B(2)=(2,1,4)
- Tp:=Tp,i と Tp,i+1 の比が B(p)i となるようにした数列(の1つ)
元のA: 6 15 20 B(2): 2 1 4 Scr B(3): 3 3 1 Scr B(5): 1 5 5 Scr ┌( 1 2 2 8 ) 32┐ ┌( 1 3 9 9 )243┐ ┌( 1 1 5 25 ) 125┐ │( 2 4 4 1 ) 32│×│( 1 3 1 1 ) 3│×│( 1 1 5 1 ) 5│ │( 2 1 1 4 ) 8│ │( 3 1 3 3 ) 27│ │( 5 5 1 5 ) 125│ └( 8 4 4 1 )128┘ └( 9 3 1 1 ) 27┘ └(25 25 5 1 )3125┘ --- --- ---- 200 300 3380
この時、各素因数の Tp としてたとえば (2,4,4,1),(1,3,1,1),(5,5,1,5) を選んだとすると、 実際の最終的な S はこれを各項毎に掛け合わせた (10,60,4,5) となる。
S のスコアは各 Tp ごとのスコア((2,4,4,1) などの各項の総積)を掛け合わせたものと一致する。
- S のスコア(各項の総積): 10×60×4×5=12000
- Tp ごとのスコアの積: 32×3×125=12000
さらに、ありえる全ての S を考えた時の総和は、以下にまとめられることが分かる。
- (全ての T2 のスコアの和)×(全ての T3 のスコアの和)×(全ての T5 のスコアの和)
つまり、上例の A=(6,15,20) に対する答えは、200×300×3380=202800000 となる。
素因数 p 毎に「全ての Tp のスコアの和」を求めれば良い。
以下のDPを考える。
- DP[i,k]:=Tp[i] までを決めて、
- 以下の条件をともに満たすような
- Tp[i] までの最小値が 1 である
- Tp[i+1]=pk となる
- 全ての Tp[:i] の総積の和
Tp[i] までは最小値が1であることを保証するが、次に置く予定である k は負であってもよいとし、遷移時に調整する。
i−1 から i の遷移へは、C(p)=logpB(p) として、基本的には Tp,i に pk を置いて
- DP[i,k+C(p)i]+=DP[i−1,k]×pk
- DP[i,k−C(p)i]+=DP[i−1,k]×pk(C(p)i≠0 の場合)
とするが、k が負の場合は最小値が1未満にならないよう、これまでの i 個全体を底上げしてから遷移する。
また、B(p) が1の場合は同じ値が続くため、1 以外になるindexだけ遷移を考えるなどで高速化できる。
Amax 以下の整数が持つ相異なる素因数の最大数を ω とすると、O(N2ωlogAmax) で全体を求められる。
E - Snuke's Kyoto Trip
問題文
- 整数 W,H,L,R,D,U が与えられます。
- 2 次元平面上に京都の町があります。
- 京都の町には、以下の条件をすべて満たす格子点 (x,y) に 1 つずつ区画が存在します。それ以外の点に区画はありません。
- 0≤x≤W
- 0≤y≤H
- x<L または R<x または y<D または U<y
- すぬけくんは、以下のように京都の町を旅しました。
- まず、区画を 1 つ選んでそこに立つ。
- その後、0 回以上好きな回数以下の操作を行う。
- x 軸正方向または y 軸正方向に 1 移動する。ただし、移動後の点にも区画がなくてはならない。
- すぬけくんが通った経路としてあり得るものの個数を 998244353 で割った余りを求めてください。
制約
- 0≤L≤R≤W≤106
- 0≤D≤U≤H≤106
- 区画が 1 つ以上存在する
- 入力はすべて整数
解法
矩形のグリッドの中に矩形の穴が空いたようなマス目において、始点終点が自由で、右と上だけの移動で到達できるような経路数を数える。
穴が空いていない場合
(0,0)~(w,h) の穴が空いていないグリッドでの答えの求め方を確認しておく。
右と上の移動回数をそれぞれ i,j(0≤i≤w,0≤j≤h)と固定すると、
- 経路数は \binom{i+j}{i}
- 始点の選び方は (w-i+1)(h-j+1)
よって、これらの総和を取って以下になる。
- \displaystyle \sum_{i=0}^{w} \sum_{j=0}^{h} \binom{i+j}{i} (w-i+1)(h-j+1)
これをWolfram Alphaさんに投げると、Σを除去して(階乗の事前計算の元で)O(1) で算出可能な形にしてくれる。
- f(w,h):=\dbinom{w+h+4}{w+2}-(w+2)(h+2)-1
また、後で必要になるので以下も計算しておく。
これは、「始点は (0,0) 固定で」終点のみ好きな位置で移動を終える場合の経路数となる。
- g(w,h):=\dbinom{w+h+2}{w+1}-1
なおこれらの式変形は、ホッケースティック恒等式から導ける。
穴が空いている場合
穴の境界に沿って、格子点を8つに分類する。
+++++++ ⑥ |⑦ |⑧ +++++++ ____|____|______ ++ +++ → ④ | |⑤ ++ +++ ____|____|______ +++++++ ① |② |③ +++++++ | |
まず、穴に関係ない(始点と終点を対角線とする矩形が穴に被らない)答えを求める。重複に注意しつつ、以下で求められる。
- ①②③を連結した矩形の f(w,h)
- + ①④⑥を連結した矩形の f(w,h)
- + ③⑤⑧を連結した矩形の f(w,h)
- + ⑥⑦⑧を連結した矩形の f(w,h)
- - ①の矩形の f(w,h)
- - ③の矩形の f(w,h)
- - ⑥の矩形の f(w,h)
- - ⑧の矩形の f(w,h)
次に、始点と終点を対角線とする矩形が穴に被るような経路を求める。
穴の左上・右下から45度の斜め線を伸ばした上にある格子点を1つ固定する。影響を受ける経路は、必ずこのどれかを1つだけ通過する。
○++++++ +○+++++ ○: 斜め線を延ばした上にある格子点 ++ +++ ◎: 今回の例で着目する格子点 ++ +++ ++++◎++ +++++○+
g(w,h) を使って、◎の左下・右上に広がる2つの矩形の経路数を求め掛け合わせると、◎を通過する経路数となる。
+++ +++ +++ +++ ++++◎++ +++++
ただし、この中には「穴に関係ない」で数えた経路も重複して数えられているので、包除原理で除く。
+++ ・・・ +++ ・・・ +++ ・・・ +++ ・・・ +++ - ・・・ - +++ + ・・・ +++ ・・・ +++ ・・・ ++++◎++ ++++◎++ ・・・・◎++ ・・・・◎++ +++++ +++++ ・・・・+ ・・・・+
これで、穴を迂回しつつ◎を通過する経路数が求められる。斜め線上の格子点それぞれについて求めればよい。