#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>=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>=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 now1: mid=(ok+ng)//2; now=ST.fold(0,mid) (ok,ng)=(mid,ng) if now