AtCoder Grand Contest 068 B問題メモ

AtCoder Grand Contest 068

1個の問題をひたすら時間かけてじっくり考えられるのは、AGCでしかできない体験。(高レート帯で鎬を削っている人は別だが)

B - 01 Graph Construction

問題文

  • 0,1 のみからなる文字列の組 $(S,T)$ が次の条件をすべて満たすとき (そしてそのときのみ) それを良い文字列組と呼ぶことにします.
    • 条件
      • $S,T$ に含まれる 0 の個数は等しい.
      • $S,T$ に含まれる 1 の個数は等しい.
    • 特に,良い文字列組 $(S,T)$ について,$S,T$ の長さは同じです.
  • 良い文字列組 $(S,T)$ に対し,無向グラフ $G(S,T)$ を次のように定義します.
    • $S$ の長さを $L$ とする.頂点 $1,2,\cdots,L$ からなるグラフ $g$ をつくる.
    • $S$ に含まれる 0 の個数を $n$ とする.
      • $S$ に含まれる 0 の index を $1 \leq a_1 \lt a_2 \lt \cdots \lt a_n \leq L$ とする.
      • $T$ に含まれる 0 の index を $1 \leq b_1 \lt b_2 \lt \cdots \lt b_n \leq L$ とする.
      • 各 $1 \leq i \leq n$ に対し,頂点 $a_i$ と頂点 $b_i$ を結ぶ辺を $g$ に追加する.
    • $S$ に含まれる 1 の個数を $m$ とする.
      • $S$ に含まれる 1 の index を $1 \leq c_1 \lt c_2 \lt \cdots \lt c_m \leq L$ とする.
      • $T$ に含まれる 1 の index を $1 \leq d_1 \lt d_2 \lt \cdots \lt d_m \leq L$ とする.
      • 各 $1 \leq i \leq m$ に対し,頂点 $c_i$ と頂点 $d_i$ を結ぶ辺を $g$ に追加する.
    • 以上の手順で得た $g$ を $G(S,T)$ とする.
  • 長さ $N$ の整数列 $A=(A_1,A_2,\cdots,A_N)$ が与えられます.
  • 以下の条件をすべて満たす良い文字列組 $(S,T)$ を $1$ つ見つけてください.
    • $S$ の長さを $L$ とする.$N \leq L \leq 10^5$ である.
    • 各 $1 \leq i,j \leq N$ について,$G(S,T)$ で頂点 $i$ と頂点 $j$ が同じ連結成分に属すとき,そしてそのときのみ $A_i=A_j$ である.
  • なお,この問題の制約下で解が必ず存在することが証明できます.

制約

  • $1 \leq N \leq 100$
  • $1 \leq A_i \leq N$
  • 入力される値はすべて整数

解法

問題文は長いが、丁寧に定義を書いているためなので、理解はしやすい。
$S,T$ の中の、0だけで $1,2,...$ 番目に出てきた同士、1だけで $1,2,...$ 番目に出てきた同士の indexと同じ番号の頂点を結んだグラフで、先頭 $N$ 頂点の連結・非連結関係を目的のものにする問題。

構築するグラフの頂点数 $L$ は $N$ よりかなり大きくても良い。
$N+1$ 以降でいろいろ頑張ってもいいよ、ということ。

実験

最終的な構築方法とは少し異なるものの、まずは実際に先頭から $S,T$ を $A$ に矛盾しないように決めてみる。

1手1手に説明を挟むと冗長になるが、まぁ、言葉より実例を見た方が早いので。。。

長いので折りたたみ

実験して、「連結にしてはいけない頂点を連結にしない」ための制約が結構厳しいことがわかった。
一度 $A_i=2$ である位置の $S_i$ に“0”を置くと、次に $T$ に“0”を置けるのは $A_j=2$ である位置しかないので、それ以外はずっと“1”を置き続けるしかない、みたいな箇所が多い。

だが、実験により、以下の傾向が見つかった。

  • 実験の構築方法では、$S$ は、$i \ge N+1$ の範囲では全て1が置かれる
  • その際、$N$ 番目以降は $A$ がいくつか除かれつつ繰り返される

$L$ の上限は、$N^2$ より大きく余裕があることと合わせ、次の構築方法が思いつく。

構築

$S$ を、「先頭 $N$ 個を“0”、それより後を全て“1”」とする。
$T$ の側は、ほぼ“1”を置くことを基本としつつ、所々に計 $N$ 個の“0”を置く。

1周に付き1個、$T$ 側に“0”を置くことを考える。

$A_i=x$ が出現するindexを順に $I(x)=(i_1,i_2,...,i_k)$ とすると、次のように構築する。

  • $l$ 周目では、「$I(A_l)$ で $l$ の次に出てくるindex(最後の場合は先頭)」に相当する頂点の $T$ に“0”を置く

「1周」「相当する頂点」などの言葉の定義が曖昧だが、言葉より図で示した方が速い。以下のようにする。

周          1                   2                 3               4             5
i: 1 2 3 4 5 6 7 8 910| ....             |                |              |            |
A: 1 2 3 4 2 5 4 2 6 2| 2 3 4 2 5 4 2 6 2| 2 3 4 5 4 2 6 2| 2 4 5 4 2 6 2| 2 4 5 2 6 2|...
S: 0 0 0 0 0 0 0 0 0 0| 1 1 1 1 1 1 1 1 1| 1 1 1 1 1 1 1 1| 1 1 1 1 1 1 1| 1 1 1 1 1 1|...
T: 0 1 1 1 1 1 1 1 1 1| 1 1 1 0 1 1 1 1 1| 1 0 1 1 1 1 1 1| 1 1 1 0 1 1 1| 1 1 1 0 1 1|...

$T$ で“0”が置かれた箇所は、$A$ に登場する数字の順になっていることがわかる。
また、$T$ に“0”が置かれた数字は、$A$ の次の周回では除かれている。

$A$ に複数回出てくる“2”に注目すると、以下のようになっている。

  • “0”によって $A$ の「1番目」の2($i=2$)と結ばれているのは、2周目で「2番目」に出現する“2”
  • “0”によって $A$ の「2番目」の2($i=5$)と結ばれているのは、5周目で(元)「3番目」に出現する“2”
    • ※2番目に出現する“2”が3周目以降除かれているため実際は2番目に出現するが、由来としては3番目

もう少し詳しく見るため、$A,S,T$ の中で $A_i=2$ に該当する箇所だけ取り出す。
1周目で出てくる順に $W,X,Y,Z$ と記号を振ると、

周    1        2       3      4      5     6    7    8   9 10    
   W X Y Z  W X Y Z  W Y Z  W Y Z  W Y Z  W Z  W Z  W Z  W  W
A: 2 2 2 2| 2 2 2 2| 2 2 2| 2 2 2| 2 2 2| 2 2| 2 2| 2 2| 2| 2|
S: 0 0 0 0| 1 1 1 1| 1 1 1| 1 1 1| 1 1 1| 1 1| 1 1| 1 1| 1| 1|
T: 1 1 1 1| 1 0 1 1| 1 1 1| 1 1 1| 1 0 1| 1 1| 1 1| 1 0| 1| 0|
            a b c d  e f g  h i j  k l m  n o  p q  r s  t  u  ┐"1"により同じ文字で
   a b c d  e   f g  h i j  k l m  n   o  p q  r s  t    u     ┘示された箇所同士が結ばれる
   w x y z                                                     ┐"0"により同じ文字で
              w                      x                y     z  ┘示された箇所同士が結ばれる

“1”によって、1周目のWと2周目のW (a)、2周目のWと3周目のW (e)、3周目のWと4周目のW (h)、、、が連結になっていく。
要するに、$W,X,Y,Z$ の記号が同じものは、全ての周を通して連結になる。
この上で、“0”を使って $W~Z$ の間を連結にする。

2周目の $T$ 側に置いた“0”(w)で、1周目のWと2周目のXが結ばれる。
つまり、全てのWと全てのXが連結になる。

5周目の $T$ 側の“0”(x)で、1周目のXと5周目のYが結ばれる。
8周目の $T$ 側の“0”(y)で、1周目のYと8周目のZが結ばれることで、全てが連結になった。

10周目の $T$ 側の“0”(z)で、1周目のZと10周目のWを結び閉じることで、 これ以降、余計な箇所と連結になることを防ぎ、完結する。

この構築方法は、$L=\frac{N(N+1)}{2}$ となり、余裕を持って $L \le 10^5$ となる。

Python3

programming_algorithm/contest_history/atcoder/2024/0929_agc068.txt · 最終更新: 2024/10/08 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0