# 競プロ講習会第5回 Web資料 #### ◎問題セット https://codeforces.com/contestInvitation/d4b2461e98073f639a5d30ae0f8d81598891fa4b #### ◎公式解説 ##### A~C問題 https://codeforces.com/blog/entry/79517 ##### D~O問題 https://codeforces.com/gym/103119/attachments/download/13796/2020icpc-macau-analyze.pdf ## ◎解説(Fまで) ### A. Required Remainder :::spoiler **◎解説** $A = \lfloor n / x \rfloor \times x$ とします。 この時、$A$ は $n$ 以下の最大の $x$ の倍数になっています。 この時、答えの候補は $A+y , A-x+y$ のどちらかです。 前者が $n$ 以下であれば前者を、そうでなければ後者を出力すればよいです。 ::: :::spoiler **◎実装例(python3)** ```python= tt = int(input()) for loop in range(tt): x,y,n = map(int,input().split()) A = n // x * x if A+y <= n: print (A+y) else: print (A-x+y) ``` ::: --- ### B. Multiply by 2, divide by 6 :::spoiler **◎解説** 値を、以下のような形式で表します。 $2^a \times 3^b \times c$ ($c$は2,3の倍数でない) さらに、値 $k$ を上の形式で表したときの$a,b,c$を $a_k,b_k,c_k$ とします。 さて、問題中の二種類の操作は以下のように言い換えられます。 * 2を掛ける操作 $2^a \times 3^b \times c$ → $2^{a+1} \times 3^b \times c$ に変更する。 * 6で割る操作 $2^a \times 3^b \times c$ → $2^{a-1} \times 3^{b-1} \times c$ に変更する。ただし、$a,b > 0$ の時しかこの操作を行えない。 まず、$c$を変更する手段はありません。そのため、$c_n$ が1ではない場合、最終的な値を1にはできないので `-1` を出力します。 最終的な値を1にするためには、以下のような方法を取るのが最適です。 1. 2を掛ける操作を繰り返し、$a = b$ にする。 2. 6を割る操作を繰り返して、$a = b = 0$ にする。 最初から $a > b$ の場合、どのように操作しても $a=b$ にできないので、`-1`を出力します。 そうでない場合、操作1を $b_n - a_n$ 回行い、操作2を $b_n$ 回行うので、答えは $2b_n - a_n$ です。 ::: :::spoiler **◎実装例(python3)** ```python= tt = int(input()) for loop in range(tt): n = int(input()) an = 0 bn = 0 cn = n while cn % 2 == 0: an += 1 cn //= 2 while cn % 3 == 0: bn += 1 cn //= 3 if cn != 1 or an > bn: print (-1) else: print (2*bn-an) ``` ::: --- ### C. Move Brackets :::spoiler **◎解説** "(" を 1 、 ")" を -1 と変換し, 数列 $a$ とします。 $b_i = a_1 + a_2 + ... + a_i$ と定義された数列$b$を考え、 $b$ の最小値を $\mathrm{min}(b)$ とします。 1. $0 \le \mathrm{min}(b)$ の時、最初からregular bracket sequenceなので、答えは0です。 2. そうでない場合、答えは $-\mathrm{min}(b)$ です。 具体的には、以下のように操作することで以上の最小値を達成できます。 1. 前から$b$を見ていき、$b_i < 0$ の場合、 $i$ 番目にある閉じかっこにチェックを付け、$i$ 以降の全ての $j(j > i)$ について、 $b_j$ に1を加える。 2. チェックを付けた全ての閉じかっこを一番後ろに移動する。 ::: --- ### D. Random Permutation :::spoiler **◎解説** 全ての $p$ についての条件を満たす確率を求め、その総和を計算すると求める答えになります。(この考え方を主客転倒と呼びます) ある $p$ について、条件を満たす$a$の個数は、$\prod_{ i = 0 }^n (n-p_i+1)$ であり、$p$ は順列であるためこの値は $n!$ と等しいです。$a$ は $n^n$ 通りありうるため、ある $p$ が条件を満たす確率は $n! / n^n$ であることが分かります。 $p$ は $n!$ 個あるため、求める答えは $n!n! / n^n$ です。 整数型だとオーバーフローするため、浮動小数点型を利用しましょう。 ::: --- ### E. Artifacts :::spoiler **◎解説(解説してません)** 頑張って読解をして、書くだけです。 記述が曖昧なところがあります(特に%関連のところ)。 とても酷い問題なので、この問題を解き直す時間は他の問題に充てましょう。 ::: --- ### F. Fixing Networks :::spoiler **◎解説** まず、$d = 0, d = 1$ の場合を処理しておきます。 $d = 0$ の時、$n = c$ ならば`Yes`であり、そうでない場合`No`です。 $d = 1$ の時、$n = 2c$ ならば`Yes`であり、そうでない場合`No`です。 構成は、適当に2頂点ずつペアにして、連結成分にしていけばよいです。 さて、以下のような部分問題を考えてみます。 * 頂点数が$m$、全ての頂点の次数が$d$である連結な単純無向グラフを構成せよ。 これは、$m,d$ がともに奇数の場合は構成できません。 全ての頂点の次数が$d$である頂点数$m$のグラフでは、辺の数を$e$とすると、$2e = md$ が成り立ちます。しかし、$m,d$が共に奇数の場合、左辺は偶数・右辺は奇数となり等式が成立しないからです。 また、$m \le d$ の場合も、構成できません。ある頂点からは$d$本の辺がそれぞれ別の頂点につながっている必要がありますが、そのためには最低でも$d+1$個の頂点がグラフに必要だからです。 条件を満たしている場合、以下のようにグラフを構築できます。 1. 頂点を円周上に等間隔に並べる。 2. $d$ が奇数の場合、ちょうど反対側にある頂点と辺を結ぶ。 3. 以下の操作を全ての頂点 $v$ について行う。 * 頂点 $v$ に関して、その頂点から時計回りに $\lfloor d/2 \rfloor$ 個先までの頂点全てに対して、$v$ との間の辺を引く。 このようにすることで、部分問題を解くことができました。 さて、元の問題を考えてみます。部分問題が解ける条件を守りつつ、$n$ 個の頂点を $c$ グループに分けます。まず、頂点数が少なすぎると構成できないので、なるべく均等に頂点を分けるのが最適であることが分かります。さらに、$m,d$ が共に奇数になってはいけない条件を考慮すると、以下のように分けるのが最適となります。 * $d$ が偶数の場合: なるべく頂点を均等に分配する。 * $d$ が奇数の場合: $n$ 個の頂点を2個ずつペアにし、ペアを単位にして頂点を均等に分配する。($n$ が奇数の場合、構成不可) あとは、各グループの部分問題を解けばよいです。 :::