---
# System prepended metadata

title: 競プロ講習会第5回 Web資料

---

# 競プロ講習会第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$ が奇数の場合、構成不可)

あとは、各グループの部分問題を解けばよいです。

:::
