見出し画像

【Atcoder】(ABC261-E)ユーザ解説コードの不思議

問題はこちら。

問題を簡単に紹介します。
入力データは、例えば次の3行で与えられます。
 3 3
 2 5
 1 12

最初の数字は演算子を意味します。
 1=And
 2=Or
 3=Xor

先ほどの3行は次の意味になります。
 3 3  3をXorする
 2 5  5をOrする
 1 12  12をAndする

初期値は別に与えられます。

この3行を次のように処理します。
初期値をXとして
 一巡目
 (1)3 3  Xに3をAndする
   Xを出力

 二巡目
 (1)3 3  Xに3をAndする
 (2)2 5  Xに5をOrする
   Xを出力

 三巡目
 (1)3 3  Xに3をAndする
 (2)2 5  Xに5をOrする
 (3)1 12  Xに12をXorする
   Xを出力

(1)(2)(3)を順に1回ずつ計算するだけなら簡単ですが、そうではないんですね。
上記のようにだんだん増えていく。
それにXの計算結果は、一巡目の結果を二巡目に、二巡目の結果を三巡目に引き継ぎます。
単純に考えると二重ループになります。
単純な私が考えたコードは次のようなものです。

def many_operations():
    (s_n, s_c) = input().split(' ')
    n = int(s_n)
    c = int(s_c)
    
    x = c
    m = 0
    t = [0 for i in range(n)]
    a = [0 for i in range(n)]
    for i in range(0, n):
        (s_t, s_a) = input().split(' ')
        in_a = int(s_a)
        in_t = int(s_t)
        
        if ((0 < m) and (in_t == t[m-1])):
            if (in_t == 1):
                a[m-1] &= in_a
            
            elif (in_t == 2):
                a[m-1] |= in_a
            
            else:
                a[m-1] ^= in_a
            
        else:
            t[m] = in_t
            a[m] = in_a
            m += 1
            
        for j in range(0, m):
            if (t[j] == 1):
                x &= a[j]
            
            elif (t[j] == 2):
                x |= a[j]
            
            else:
                x ^= a[j]
            
        print(x)
    
many_operations()

正しい結果を得るという意味ではあってる。
ただ、Atcoder の競技では、1回の処理は2秒以内に完了すること、という条件があります。
更に、入力データの数の上限は「200000」。
上記のサンプルデータはたった3行でしたが、これが最大200000行ある。
最悪、「200000 * 200000 / 2」回ループします。
1秒に「100,000,000」ループが目安だそうですが、とうてい足りません。

うんうん唸ったあげく、解説コードを拝見しました。
公式解説はみてもわからなかったんだけど(苦笑)、とても興味深かったのがユーザ解説です。
そのコードがこちら。

これがねぇ。
すごいんです。
コードがあまりにもシンプルで。
「ほんとに同じ結果が得られるの?」
と訝しくさえ思った私は試しました。
もちろん、同じ結果でした。

なんで同じになるんだろう。
どうやったらこんなコードを思い付くんだろう。

ただただ感嘆したことでした。








この記事が気に入ったらサポートをしてみませんか?