1. paizaラーニングトップ
  2. レベルアップ問題集
  3. ハッシュメニュー応用編(言語選択)
  4. 問題一覧 Swift編
  5. マークル木とは

ハッシュメニュー応用編のサムネイル
マークル木とは (paizaランク B 相当)

問題にチャレンジして、ユーザー同士で解答を教え合ったり、コードを公開してみよう!

問題

下記の問題をプログラミングしてみよう!

ハッシュ関数は様々なデータの要約・検証に使うことができます。そのうちのひとつがマークル木(マークルツリー)です。マークル木とは、ノードにハッシュ値をもつ二分木で、それぞれ親ノードには子ノードのハッシュ値を結合したものを入力として得られるハッシュ値が割り当てられています。特に、木構造の根の部分のハッシュ値をルートハッシュと呼びます。以下の例を参考にしてください。



本問では、マークル木におけるデータの要約をしてみましょう。

整数 N が与えられ、その後 2N 個の文字列 d_i (1 ≦ i ≦ 2N) が与えられます。以下のハッシュ関数 H を用いて、これらの文字列から計算されるルートハッシュ h を出力してください。なお、親ノードのハッシュ値 hb を計算する際は、上の画像のように、隣同士の子ノードのハッシュ値 hb0 と hb1 を順番に文字列として結合させて得た新たな文字列を入力として計算してください。片方の子ノードがない場合、一つの子ノード hb0 を複製して結合させた文字列を新たな入力とするやり方などがありますが、今回の問題で扱うマークル木は完全二分木のためそのような場合は起こりません。

文字列 s の長さを m として、

H(s) = (s の 1 文字目の文字コード * B1 + s の 2 文字目の文字コード * B2 + ... + s の m 文字目の文字コード * Bm) % mod

ただし、B = 108+7, mod = 109+7 とし、文字コードは ASCII に従って変換してください。

入力される値

N
d_1
d_2
...
d_2N

  • 1 行目に、木構造の階層の数を表す整数 N が与えられます。

  • i+1 行目に、データを表す文字列 d_i が与えられます。(1 ≦ i ≦ 2N)

  • d_i はマークル木の末端のノードと対応しており、順番に左端のノードには d_i が対応し、右端のノードには d_2N が対応しています。

  • 入力値最終行の末尾に改行が1つ入ります。
    文字列は標準入力から渡されます。 標準入力からの値取得方法はこちらをご確認ください
    期待する出力

    ルートハッシュを計算し、1 行で出力してください。

    また、末尾に改行を入れ、余計な文字、空行を含んではいけません。

    条件

    すべてのテストケースにおいて、以下の条件をみたします。

  • 0 ≦ N ≦ 10

  • d_i は半角英数字で構成される長さ 1 以上 10 以下の文字列
  • 入力例1

    2
    apple
    banana
    chocolate
    donut

    出力例1

    796394619

    入力例2

    0
    paiza

    出力例2

    996055667

    問題一覧へ戻る

    ページの先頭へ戻る