結果
問題 | No.2308 [Cherry 5th Tune B] もしかして、真? |
ユーザー | navel_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 | - |
ソースコード
#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)