Slide 1

Slide 1 text

yukicoder contest 446 解説 seekworser/ぷせうど

Slide 2

Slide 2 text

◼ Milk ★1: AC 100人 ◼ Minahoshi (Easy) ★1.5: AC 99人 ◼ Mamehinata ★2: AC 71人 ◼ Chiffon ★2.5: AC 65人 ◼ Rusk ★2.5: AC 23人 ◼ Mint ★3: AC 44人 ◼ Lime and Karin ★4: AC 18人 ◼ Minahoshi (Hard) ★4: AC 3人 問題セット

Slide 3

Slide 3 text

A: Milk

Slide 4

Slide 4 text

かわいいですね Milk https://komado.booth.pm/items/2953391

Slide 5

Slide 5 text

問題概要

Slide 6

Slide 6 text

解法 ◼ さすがにやるだけ ◼ if 文を使って D が100以下かどうか判定すれば良い ◼ コードゴルフとかもできそう 解答例(Python)

Slide 7

Slide 7 text

元ネタ ◼ MOFEというサイトがある。 ◼ 難易度に飲み物(主に紅茶)の名前が使われており、最低難易度がMilk

Slide 8

Slide 8 text

B: Minahoshi (Easy)

Slide 9

Slide 9 text

かわいいですね Minahoshi https://mukumi.booth.pm/items/2693309

Slide 10

Slide 10 text

問題概要

Slide 11

Slide 11 text

LCP arrayとは? ◼ すべての接尾辞を辞書順に並べてソートした配列で、隣り合う文字列が先頭から何文字一致しているか 元の文字列:abba a ba bba abba 接尾辞 辞書順にソート a ba bba abba 1 0 1 先頭から何文字 一致しているか

Slide 12

Slide 12 text

解法 ◼ LCP arrayの総和を最大化したい → なるべく隣同士に同じような文字列が並ぶと良さそう……? すべて同じ文字で揃えるとよさそう aaa...... もしくは bbb...... を出力するとAC ◼ 丁寧に証明するのはややめんどう

Slide 13

Slide 13 text

C: Mamehinata

Slide 14

Slide 14 text

かわいいですね Mamehinata https://mukumi.booth.pm/items/4340548

Slide 15

Slide 15 text

問題概要

Slide 16

Slide 16 text

問題概要

Slide 17

Slide 17 text

問題概要

Slide 18

Slide 18 text

問題概要

Slide 19

Slide 19 text

問題概要

Slide 20

Slide 20 text

問題概要

Slide 21

Slide 21 text

解法 ◼ BFS木(BFS tree)というものがある ◼ グラフについてBFSで通る辺だけ残したグラフは木になる ◼ 根からの最短距離が d の頂点には、 必ず根からの最短距離が d-1 の頂点から辺が 張られている ◼ 元のグラフにおいて、BFS木の深さが 2 以上 異なる頂点同士を結ぶ辺は無い

Slide 22

Slide 22 text

解法 ◼ BFS木(BFS tree)というものがある ◼ グラフについてBFSで通る辺だけ残したグラフは木になる ◼ 根からの最短距離が d の頂点には、 必ず根からの最短距離が d-1 の頂点から辺が 張られている ◼ 元のグラフにおいて、BFS木の深さが 2 以上 異なる頂点同士を結ぶ辺は無い → 今塗られている深さの頂点に対して、 → 深さの差が1となる深さの頂点が → すべて塗られる 時刻 1:深さ 1 時刻 2:深さ 0, 2 時刻 3:深さ 1, 3, 5 ◼ あらかじめBFSで各頂点の深さを計算しておけば O(N+M) で解くことができる

Slide 23

Slide 23 text

注意 頂点1が孤立点の場合は、時刻1以降すべての頂点が白くなってしまう

Slide 24

Slide 24 text

注意 頂点1が孤立点の場合は、時刻1以降すべての頂点が白くなってしまう

Slide 25

Slide 25 text

余談 ◼ まじでごめんなさい ◼ コーナー見えにくいだろうな~~と思って出したら、案の定ペナ量産問題に……

Slide 26

Slide 26 text

D: Rusk

Slide 27

Slide 27 text

かわいいですね Rusk https://komado.booth.pm/items/2559783

Slide 28

Slide 28 text

問題概要

Slide 29

Slide 29 text

問題概要 A B B B C C C C B B B A A 1回めのトースター 2回めのトースター ◼ あり得るすべての焼き方について、美味しさの総和の最大値を求める

Slide 30

Slide 30 text

問題概要 1回めのトースター ◼ とりあえず、1回目のトースターだけについて考えると、1~Nの区間を3つの状態に分割できる ◼ これらの状態の遷移は一方通行で、戻ることはできない 1 2 3 初期状態 トースターin トースターout DP[i][j] = (i番目のパンまで見て、状態がjのときの美味しさの最大値)として解ける

Slide 31

Slide 31 text

問題概要 ◼ トースターが2台になると? ◼ 大きくは解法は変わらない ◼ 1台目のトースターと2台目のトースターの状態をかけ合わせた状態について動的計画法を行う DP[i][j][k] = (i番目のパンまで見て、1台目のトースターの状態がj、2台目のトースターの状態 がkのときの美味しさの最大値) 1回めのトースター 2回めのトースター

Slide 32

Slide 32 text

余談 ◼ Ruskは「パンを2度焼きした焼き菓子」という意味らしい、へ~~~

Slide 33

Slide 33 text

E: Chiffon

Slide 34

Slide 34 text

かわいいですね Chiffon https://komado.booth.pm/items/5354471

Slide 35

Slide 35 text

問題概要

Slide 36

Slide 36 text

問題概要 ◼ どのピースにもいちごが 1 つ以上乗るように切り分ける

Slide 37

Slide 37 text

問題概要 ◼ どのピースにもいちごが 1 つ以上乗るように切り分ける 4 4 4 最小のピースを最大化

Slide 38

Slide 38 text

解法 ◼ 最小のピースを最大化……? ◼ とても二分探索したくなる見た目! ◼ Yokan Party(競プロ典型90問 問題1)とよく似ており、実際切れ目をいれる箇所を1箇所決めれ ば、ほぼ同じ解法で解くことができる。

Slide 39

Slide 39 text

解法 ◼ 最小のピースを最大化……? ◼ とても二分探索したくなる見た目! ◼ Yokan Party(競プロ典型90問 問題1)とよく似ており、実際切れ目をいれる箇所を1箇所決めれ ば、ほぼ同じ解法で解くことができる。 判定問題:4以上で切り分けられるか? 切れ目を固定 6 4 2 No

Slide 40

Slide 40 text

解法 ◼ 最小のピースを最大化……? ◼ とても二分探索したくなる見た目! ◼ Yokan Party(競プロ典型90問 問題1)とよく似ており、実際切れ目をいれる箇所を1箇所決めれ ば、ほぼ同じ解法で解くことができる。 判定問題:4以上で切り分けられるか? 切れ目を固定 4 Yes 4 4

Slide 41

Slide 41 text

解法 ◼ 切れ目の位置を1つ固定した問題は O(K log N) で解ける ◼ 切れ目の位置の候補は O(N) なので、全体で O(NK log N) となって間に合わない……

Slide 42

Slide 42 text

解法 ◼ 切れ目の位置を1つ固定した問題は O(K log N) で解ける ◼ 切れ目の位置の候補は O(N) なので、全体で O(NK log N) となって間に合わない…… 本当か?

Slide 43

Slide 43 text

解法 ◼ 切れ目の位置を1つ固定した問題は O(K log N) で解ける ◼ 切れ目の位置の候補は O(N) なので、全体で O(NK log N) となって間に合わない…… 本当か? ◼ いちごは全部で K 個あるので、いちご同士の間隔であって、あいだの長さが 2N/K 以下であるような箇所が 必ず 1 箇所以上存在する。 ◼ いちご同士の間隔にはすべて切れ目をいれるので、その間隔にある切れ目候補だけ全探索すれば良い O(N/K * K log N) = O(N log N)で解くことができる

Slide 44

Slide 44 text

余談 ◼ ABC370F に円環状のYokan Partyが出題されて爆破されたかと思ったけど、若干解法が違って耐えてた

Slide 45

Slide 45 text

F: Mint

Slide 46

Slide 46 text

かわいいですね Mint https://komado.booth.pm/items/2258111

Slide 47

Slide 47 text

問題概要

Slide 48

Slide 48 text

問題概要 ◼ 制約が10の12乗……? → N or M の ½ 乗の解法が怪しそう ◼ k が小さいところは愚直に計算するとして、kが大きいところで効率的に計算できないか考えたい

Slide 49

Slide 49 text

問題概要 ◼ 制約が10の12乗……? → N or M の ½ 乗の解法が怪しそう ◼ k が小さいところは愚直に計算するとして、kが大きいところで効率的に計算できないか考えたい ◼ M = k*d + r (r < k)として表したとき、M mod k (= r)は M – k*d のように表せる ◼ k が大きいとき、dとして考えられる値の候補は少ない ◼ 具体的には、k ≧ √M のとき、d の候補は √M 以下の値しか存在しない ◼ d を固定した場合の問題については等差数列の和の形になるので、d ごとに O(1) で計算可能 k < √M と k ≧ √Mで場合分けをして、k が大きい場合は d の値に応じて解くことによって O(√M) で計算可能

Slide 50

Slide 50 text

余談 ◼ 実装が結構めんどう(おなじところを重複して数えないようにするなど工夫が必要)なのでこの位置に ◼ 制約メタ読みで解法自体はかなり生えやすいと思う ◼ 直近の yukicoder 445 (菁々祭プログラミングコンテスト2024) でかなり近い問題が出されたけど、 一応解説にこちらの想定解はなかったので強行…… ◼ Mintの想定解のNとMを入れ替えて、x=1,2,…,N について解くことで、O(N√N) で解けるはず…

Slide 51

Slide 51 text

G: Lime and Karin

Slide 52

Slide 52 text

かわいいですね Lime https://komado.booth.pm/items/4876459

Slide 53

Slide 53 text

かわいいですね Karin https://komado.booth.pm/items/3470989

Slide 54

Slide 54 text

問題概要

Slide 55

Slide 55 text

問題概要 2 3 1 4 5 (l,r)=(1,1),(1,2),(1,5),(2,2),(2,3), (2,5),(5,5) が条件を満たす → 答えは 7個

Slide 56

Slide 56 text

解法 2 3 1 4 5 ◼ 頂点 1 を通るパスであって、条件を満たすものを考える ◼ さらに、①頂点1を端点とするもの ②頂点1が端点でないもの に分けると、①の方は簡単に求めること ができる(頂点1から開始してDFSをすれば良い)

Slide 57

Slide 57 text

2 3 1 4 5 ◼ 頂点 1 を通るパスであって、②頂点1が端点でないもの ある部分木から別の部分木に行く方法で条件を満たすもの 解法

Slide 58

Slide 58 text

2 3 1 4 5 ◼ 頂点 1 を通るパスであって、②頂点1が端点でないもの ◼ ライムの木を1、カリンの木を-1として、頂点1からの距離を指数とする多項式を各部分木ごとに考える ある部分木から別の部分木に行く方法で条件を満たすもの f1 = x f2 = x^-2 + x^-1 + 1 解法

Slide 59

Slide 59 text

2 3 1 4 5 ◼ 頂点 1 を通るパスであって、②頂点1が端点でないもの ◼ ライムの木を1、カリンの木を-1として、頂点1からの距離を指数とする多項式を各部分木ごとに考える ある部分木から別の部分木に行く方法で条件を満たすもの f1 = x f2 = x^-2 + x^-1 + 1 = ∑_{k=-1,0,1,…} [x^k] f1 f2 解法

Slide 60

Slide 60 text

◼ 部分木が 3 つ以上だったら? ◼ 「異なる部分木同士の多項式の積の総和」は O(N log N) で計算できる ◼ tatyam さんのスライドが詳しい https://speakerdeck.com/tatyam_prime/gao-nan-yi- du-mu-wen-ti-wojie-kutekunitukuji 解法

Slide 61

Slide 61 text

◼ 頂点 x を含むパスについての解が木の頂点数 N に対して O(N log N) で求まる 木を重心分解して再帰的に解くことで全体 O(N log^2 N) で解くことができる 解法

Slide 62

Slide 62 text

余談 ◼ ★4 の 2 問のうちかなりストレートな典型枠 ◼ 解法としては LC の Frequency Table of Tree Distance と基本的に同じ ◼ 負の冪を扱う必要がある部分が少し違うくらい ◼ 実装がまじで苦しい、大変だった、みんなも苦しんでほしい

Slide 63

Slide 63 text

H:Minahoshi (Hard)

Slide 64

Slide 64 text

私です

Slide 65

Slide 65 text

問題概要

Slide 66

Slide 66 text

解法 ◼ とりあえず実験してみる N=2: ab N=3: abb N=4: aabb N=5: bbaab N=6: abbaaa N=7: bbaaaba N=8: bbaaabab N=9: baaababbb N=10: bbbaaababb N=11: aababbbaaaa 総和 0 総和 1 総和 2 総和 3 総和 5 総和 7 総和 9 総和 11 総和 13 総和 16

Slide 67

Slide 67 text

◼ とりあえず実験してみる N=2: ab N=3: abb N=4: aabb N=5: bbaab N=6: abbaaa N=7: bbaaaba N=8: bbaaabab N=9: baaababbb N=10: bbbaaababb N=11: aababbbaaaa 総和 0 総和 1 総和 2 総和 3 総和 5 総和 7 総和 9 総和 11 総和 13 総和 16 +1 +1 +1 +2 +2 +2 +2 +2 +3 解法

Slide 68

Slide 68 text

◼ とりあえず実験してみる ◼ 総和の隣接差分が増えるタイミングでは何が起きている? N=2: ab N=3: abb N=4: aabb N=5: bbaab N=6: abbaaa N=7: bbaaaba N=8: bbaaabab N=9: baaababbb N=10: bbbaaababb N=11: aababbbaaaa 総和 0 総和 1 総和 2 総和 3 総和 5 総和 7 総和 9 総和 11 総和 13 総和 16 +1 +1 +1 +2 +2 +2 +2 +2 +3 解法

Slide 69

Slide 69 text

◼ とりあえず実験してみる ◼ 総和の隣接差分が増えるタイミングでは何が起きている? N=2: ab N=5: bbaab N=10: bbbaaababb →長さ1の連続部分列にa,bが一度ずつ →長さ2の連続部分列にaa,ab,ba,bbが一度ずつ →長さ3の連続部分列にaaa,aab,aba,abb,baa,bba,bab,bbb →が一度ずつ なるべく異なる連続部分列を文字列中に含めたい 解法

Slide 70

Slide 70 text

aaa aab aba abb baa bab bba bbb 1 2 3 4 5 6 7 8 頂点番号 対応する文字列 接続可能な頂点 1, 2 3, 4 5, 6 7, 8 1, 2 3, 4 5, 6 7, 8 ◼ 長さ k の文字列を頂点として、各頂点の末尾の k−1 文字が、隣接する頂点の先頭 k−1 文字と一致す るように辺を張った有向グラフを考える i=1,…,2^{k-1}について ⌊x/2⌋ = i となるような頂点を全て通り、 指定された長さとなるパスを1つ構築する 解法

Slide 71

Slide 71 text

aaa aab aba abb baa bab bba bbb 1 2 3 4 5 6 7 8 頂点番号 対応する文字列 接続可能な頂点 1, 2 3, 4 5, 6 7, 8 1, 2 3, 4 5, 6 7, 8 ◼ 長さ k の文字列を頂点として、各頂点の末尾の k−1 文字が、隣接する頂点の先頭 k−1 文字と一致す るように辺を張った有向グラフを考える ◼ 長さ 2^{k-1}+1 で、[1と2のいずれか][3と4のいずれか]…[7と8のいずれか]の頂点を全て通り、始点と 終点が一致するウォークが1つ取れたとする。このとき使用した頂点をすべて削除する →残るグラフは、各頂点の入次数と出次数が1となるグラフであり、いくつかのサイクルに分割できる →サイクルの始点と終点で、元のサイクルと行き先をswapすることでサイクルの長さを徐々に大きくできる (詳しい操作は解説を見てください……) 解法

Slide 72

Slide 72 text

aaa aab aba abb baa bab bba bbb 1 2 3 4 5 6 7 8 頂点番号 対応する文字列 接続可能な頂点 1, 2 3, 4 5, 6 7, 8 1, 2 3, 4 5, 6 7, 8 ◼ 長さ k の文字列を頂点として、各頂点の末尾の k−1 文字が、隣接する頂点の先頭 k−1 文字と一致す るように辺を張った有向グラフを考える ◼ 長さ 2^{k-1}+1 で、[1と2のいずれか][3と4のいずれか]…[7と8のいずれか]の頂点を全て通り、始点と 終点が一致するウォークが1つ取れたとする。このとき使用した頂点をすべて削除する →残るグラフは、各頂点の入次数と出次数が1となるグラフであり、いくつかのサイクルに分割できる →サイクルの始点と終点で、元のサイクルと行き先をswapすることでサイクルの長さを徐々に大きくできる (詳しい操作は解説を見てください……) どうやって? 解法

Slide 73

Slide 73 text

解法 https://ja.wikipedia.org/wiki/M%E7%B3%BB%E5%88%97

Slide 74

Slide 74 text

◼ 線形漸化式で乱数を生成する際に、漸化式を原始多項式とすることで0を除く任意のパターンを生成可能 であることが知られている ◼ 証明は http://www.math.sci.hiroshima-u.ac.jp/m-mat/TEACH/0407-2.pdf など ◼ したがって、これで初期解を構成して徐々に伸ばしていけば良い。 解法

Slide 75

Slide 75 text

◼ ★4のややアドホック枠 ◼ 最初 2 乗で提出したら Tester さんに線形にしてもらいました、ありがとう…… ◼ 1st UC で既出らしい、そんな…… 解法