0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ABC284-F ABCBAC (Python)

Posted at

問題

解き方

ローリングハッシュ。
クラス化したものを自分で持っとくとラクそう。あとでやろ。
ローリングハッシュの説明自体は、他の記事だったり本だったりにおまかせします。

具体的な方法

入力例1の「abcbac」でやってみます。
最初は、左半分の「abc」と、右半分を反転させた「cab」が一致してるかどうかを見る。
ここからローリングします。i(1≦i≦N)回目の操作では、
・左半分の「abc」→ 右からi番目の文字を消す「ab」→さっき消した位置に今度は元の文字列の右からi番目の文字を挿入する「abc」
・右半分を反転させた「cab」→ 先頭の文字を消す「ab」→末尾に元の文字列のN-i+1文字目を挿入する「abc」
のように文字列を動かして、同じかどうか判定します。
細かいことはコードを見てください。

ACコード

import random

N = int(input())
T = input()

# hash_dic[(英小文字)] = 乱数
hash_dic = dict()
for i in range(26):
    alp = chr(97 + i)  # chr(97)='a'だよ
    rd = random.randint(1, 2 ** 60)
    hash_dic[alp] = rd

a = random.randint(2, 2 ** 60)
mod = random.randint(2 ** 63, 2 ** 64)

# rui_a[i]: a^iをmodで割ったあまり
rui_a = []
num = 1
for _ in range(N):
    rui_a.append(num)
    num = num * a % mod

# 最初は、文字列Tがf_N(S)かどうかの確認をしてみる。
# ということで、文字列Tの左半分をローリングハッシュ
val_base = 0
for i in range(N):
    t = T[i]
    val_base += rui_a[N - 1 - i] * hash_dic[t] % mod
    val_base %= mod

# 文字列Tの右半分を「反転させたもの」をローリングハッシュ
val_rev = 0
for i in range(N):
    t = T[2 * N - 1 - i]
    val_rev += rui_a[N - 1 - i] * hash_dic[t] % mod
    val_rev %= mod

# 入力例3みたいなパターンだけ先に個別で処理しとく。
if val_base == val_rev:
    print(T[:N])
    print(N)
    exit()

for i in range(N):
    # val_baseは、末尾のT[N-1-i]を取り除いて、末尾にT[2*N-1-i]をつけ加える。
    val_base -= rui_a[i] * hash_dic[T[N - 1 - i]] % mod
    val_base += rui_a[i] * hash_dic[T[2 * N - 1 - i]] % mod
    val_base %= mod

    # val_revは、(右側を先頭として)先頭のT[2*N-1-i]を取り除いて、末尾にT[N-1-i]をつけ加える。
    val_rev -= rui_a[N - 1] * hash_dic[T[2 * N - 1 - i]] % mod
    val_rev %= mod
    val_rev *= a  # 文字列の先頭の位置が1つ左にずれてるから、各項の係数をそれぞれa倍してあげる。
    val_rev += rui_a[0] * hash_dic[T[N - 1 - i]] % mod
    val_rev %= mod

    if val_base == val_rev:
        print(T[:N - 1 - i] + T[2 * N - 1 - i:])
        print(N - 1 - i)
        exit()

print(-1)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?