結果

問題 No.2308 [Cherry 5th Tune B] もしかして、真?
ユーザー navel_tosnavel_tos
提出日時 2023-05-19 23:14:03
言語 PyPy3
(7.3.15)
結果
WA  
実行時間 -
コード長 3,485 bytes
コンパイル時間 183 ms
コンパイル使用メモリ 82,176 KB
実行使用メモリ 136,920 KB
最終ジャッジ日時 2024-05-10 06:34:30
合計ジャッジ時間 7,250 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 49 ms
53,760 KB
testcase_01 WA -
testcase_02 TLE -
testcase_03 TLE -
testcase_04 TLE -
testcase_05 TLE -
testcase_06 TLE -
testcase_07 TLE -
testcase_08 TLE -
testcase_09 TLE -
testcase_10 TLE -
testcase_11 TLE -
testcase_12 TLE -
testcase_13 TLE -
testcase_14 TLE -
testcase_15 TLE -
testcase_16 TLE -
testcase_17 TLE -
testcase_18 TLE -
testcase_19 TLE -
testcase_20 TLE -
testcase_21 TLE -
testcase_22 TLE -
testcase_23 TLE -
testcase_24 TLE -
testcase_25 TLE -
testcase_26 TLE -
testcase_27 TLE -
testcase_28 TLE -
testcase_29 TLE -
testcase_30 TLE -
testcase_31 AC 1,809 ms
135,716 KB
testcase_32 AC 1,825 ms
134,832 KB
testcase_33 AC 1,772 ms
135,524 KB
testcase_34 AC 1,774 ms
136,488 KB
testcase_35 AC 1,706 ms
136,920 KB
testcase_36 WA -
testcase_37 WA -
testcase_38 TLE -
権限があれば一括ダウンロードができます

ソースコード

diff #

#yukicoder389D

'''
■考察欄
しんどそうな問題だなぁ。

T/F と 論理演算子を与える。
すげ替えを行うので、論理演算結果が最終的にどうなるか示せ。

愚直にやると、間に合わないか?

impがややこしいな。
T→T : T
T→F : F
F→T : T
F→F : T

dequeみたいなデータ構造があると楽なんだが、そんなものはない。
対決順を定められたらなぁ。

本当にやりたくないですがクエリ平方分割してやります。
区間を√N個に分割し、愚直に論理演算をやります。

区間をまたぐときが怖いから、追加ルールとして
「演算結果は左側に格納する」というものを用意しよう。

っていうか、残っている演算子の数さえわかればいいのでは?
「左からx番目の演算子はなんですか」が分かればいいなら、それはもうセグ木でいける。
'''
#Segment Tree: O(logN)
class SegmentTree:
    def __init__(self,n,identity_e,combine_f):
        self._n=n;self._size=1
        while self._size<self._n:self._size<<=1
        self._identity_e=identity_e;self._combine_f=combine_f;self._node=[self._identity_e]*2*self._size
    def build(self,array):
        assert len(array)==self._n,'array too large'
        for i,v in enumerate(array,start=self._size):self._node[i]=v
        for i in range(self._size-1,0,-1):self._node[i]=self._combine_f(self._node[i<<1|0],self._node[i<<1|1])
    def update(self,index,value):  #一点更新
        i=self._size+index;self._node[i]=value
        while i-1:i>>=1;self._node[i]=self._combine_f(self._node[i<<1|0],self._node[i<<1|1])
    def fold(self,L,R):  #区間取得: [L,R)の区間値を得る
        L+=self._size;R+=self._size;vL,vR=[self._identity_e]*2
        while L<R:
            if L&1:vL=self._combine_f(vL,self._node[L]);L+=1
            if R&1:R-=1;vR=self._combine_f(self._node[R],vR)
            L>>=1;R>>=1
        return self._combine_f(vL,vR)


from collections import defaultdict as dd
add=lambda x,y:x+y

for _ in range(int(input())):
    N=int(input()); X=list(map(lambda x: x=='True',input().split())); Y=input().split()
    S=list(map(int,input().split()))
    ST=SegmentTree(N,0,add); ST.build([1]*N)

    for i in S:  #左からi番目の真偽値と、i+1番目の真偽値を特定せよ。
        #1. 左からi番目の真偽値のインデックスを特定する
        #[0,x) の中に、まだ計算されていない真偽値がちょうどi-1個で、
        #[0,x+1) だと、真偽値がちょうどi個になる。
        #ok: 真偽値がi個未満、ng: 真偽値がi個以上 で判定しよう。
        ok,ng=0,N  #[0,x)に真偽値がいくつあるか?
        while abs(ok-ng)>1:
            mid=(ok+ng)//2; now=ST.fold(0,mid)
            (ok,ng)=(mid,ng) if now<i else (ok,mid)
        Lt=ok; ng=N
        #次に、[0,x)の中に真偽値がi+1個あるものを探す
        while abs(ok-ng)>1:
            mid=(ok+ng)//2; now=ST.fold(0,mid)
            (ok,ng)=(mid,ng) if now<i+1 else (ok,mid)
        Rt=ok
        #LtとRtの真偽値を合成し、Rt側に格納する
        ope=Y[Rt-1]
        if ope=='and': end=(X[Lt] and X[Rt])
        if ope=='or':  end=(X[Lt] or  X[Rt])
        if ope=='xor': end=(X[Lt]^X[Rt])
        if ope=='imp':
            if X[Lt]==True and X[Rt]==False: end=False
            else: end=True
        X[Rt]=end; ST.update(Lt,0)
    print(end)
0