AT274の技術だったりなかったり

あっとのTECH LOG

競プロのこととか技術のこととか。たまに日常を書きます。

ABC158 D - String Formation

問題原文

atcoder.jp

問題要旨

英子文字からなる  S があり、これに対しての操作クエリが  Q 個与えられる。
クエリには2種類ある。

  1. 反転クエリ: 現状の  S を反転する
  2. 文字追加クエリ:  S の (先頭:  f=1 / 末尾:  f=2) に 英子文字 c を追加する

 Q 個のクエリを処理したあとに出来上がる  S を求めよ。

  •   1 \leq |S| \leq 10^{5}
  •  1 \leq Q \leq 10^{5}

解法

毎回愚直に反転処理をしていては間に合わないので何か工夫する必要がある。
少し考えると、「反転しているかどうか」の状態だけ持っておけば、文字追加クエリについて結局どちらに追加すればいいのかがわかるので、最後に構築できる。

実装

「未反転状態かつ先頭追加」「反転状態かつ末尾追加」の時は先頭追加、
「未反転状態かつ末尾追加」「反転状態かつ先頭追加」の時は末尾追加、 というようになっているので、工夫すると条件式が排他的論理和で楽に書ける。

S = list(input())
Q = int(input())
reverse, front, tail = False, [], []

for q in range(Q):
    query = list(input().split())

    # 反転クエリ 
    if len(query) == 1:
        reverse ^= 1

    # 文字追加クエリ
    elif len(query) == 3:
        f, c = int(query[1]), query[2]
        f -= 1  # XORで判定できるように-1しておく

        if f ^ reverse:
            tail.append(c)
        else:
            front.append(c)

if reverse:
    print(''.join((front[::-1] + S + tail)[::-1]))
else:
    print(''.join(front[::-1] + S + tail))

感想

こういう考え方のXOR判定が解法になる問題がどこかにあった気がするなぁ。。。