ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

エクサウィザーズ 2019 C - Snuke the Wizard

問題
提出コード

解法

後ろから見ると見通しがよくなるパターンの問題です。
”消滅しないロボットの左端"をlとします。これを、O(Q)で求めていきます。同様に右端をrとし、最後にその区間に含まれるロボットの数、つまりr-l+1を求めれば答えとなります。
左端と右端は、正反対のことを考えればよいので、とりあえず左端、lについて求めることを考えます。
このとき、一番左、1番目のロボットが消滅するためには、すくなくとも
"s_{1} \  L"
という入力が必要です。
同様に考えていくと、
i番目のロボットが消滅するためには、すくなくとも
"s_{i} \  L"
という入力があり、かつ
それより後に、
"s_{i-1} \  L", "s_{i-2} \  L", ... "s_{1} \  L"
の順番でどこかしらにこれらの入力が存在している必要があります。
ということで、この条件をふまえると、i番目が消滅するとき、i-1は必ず消滅するため、初期値l=1として、呪文を後ろから順番に確認していき、
"s_{l} \  L"
という入力が合った場合にlを1増やす、という操作を行っていけば良さそうです。
が、このままだと矛盾するケースがあり、
"s_{l-1} \  R"
という入力が存在していた場合です。
lの定義より、l未満のロボットはすべて消滅するはずですが、上のような入力が出てきた場合、l-1番目のマスに存在しているロボットは、"s_{l-1} \  L"という入力よりも前に反対方向に進んでしまうため、最終的に消滅することはありません。
逆に、l+1以上のマス目に存在しているロボットも、すくなくともl番目のマスにしか来れないため、消滅することはありません。
加えて、l-1未満のマス目に存在しているロボットは、"s_{l-1} \  R"
で影響を受けることはないため、結果的に次のような操作をすればよいです。

  • "s_{l-1} \  R"の入力が来た場合はlを1減らす


まとめると、初期値をl=1として、呪文を後ろから見ていき、

  • "s_{l} \  L"の入力が来た場合はlを1増やす

  • "s_{l-1} \  R"の入力が来た場合はlを1減らす

という操作を行っていけば、”消滅しないロボットの左端"lが求まります。
rについてもほぼ同じことを行えば、r-l+1が答えになります。

感想

最初見たときは解けなくてDへ逃げたのですが、冷静に考えてみると、後ろからやっていくのがよさそう、となったので実装しました。
"s_{l-1} \  R"のコーナーケースに気づいたのが提出をしてからで、解法自体はほぼエスパーでした…
証明もふわっとしかできていないので(これで嘘だったらごめんなさい)、ここが今後の課題かと思います!