結果
問題 | No.2265 Xor Range Substring Sum Query |
ユーザー | とりゐ |
提出日時 | 2023-03-12 03:54:52 |
言語 | PyPy3 (7.3.15) |
結果 |
RE
|
実行時間 | - |
コード長 | 2,696 bytes |
コンパイル時間 | 597 ms |
コンパイル使用メモリ | 82,080 KB |
実行使用メモリ | 347,820 KB |
最終ジャッジ日時 | 2024-09-25 00:34:58 |
合計ジャッジ時間 | 7,869 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 38 ms
53,280 KB |
testcase_01 | AC | 38 ms
53,320 KB |
testcase_02 | RE | - |
testcase_03 | AC | 135 ms
77,604 KB |
testcase_04 | TLE | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
testcase_10 | -- | - |
testcase_11 | -- | - |
testcase_12 | -- | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
ソースコード
class non_commutative_xor_segment_tree: def __init__(self,n,init,ope,E): self.n=n # 配列のサイズは 2**n self.N=1<<n self.ope=ope # モノイドの演算 self.E=E # モノイドの単位元 self.node=[[E]*self.N for _ in range(n+1)] # テーブルを構築する.O(n*2**n) # node[i][j] には A_{j^0}, A_{j^1}, ..., A_{j^(2**i-1)} の情報を持たせる for j in range(self.N): self.node[0][j]=init[j] # init は初期配列 for i in range(1,n+1): for j in range(self.N): self.node[i][j]=self.ope(self.node[i-1][j],self.node[i-1][j^(1<<(i-1))]) # 各ノードの最終更新時刻を記録 self.last_update=[[0]*self.N for i in range(n+1)] self.time=1 # 各ノードが更新すべき最新の時刻 # 通常のセグ木と同じノードの持ち方(頂点番号の割り当て方)をする self.lazy=[0]*2*self.N def update(self,x,k): # A_x=k とセットする self.node[0][x]=k self.last_update[0][x]=self.time # ノードの更新するべき最新の時刻を上書き # この処理は O(n) for i in range(self.n+1): self.lazy[(x+self.N)>>i]=self.time self.time+=1 def get(self,i,j): # 最新の node[i][j] を求める # last_update[i][j] がすでに最新(==self.lazy[(j+self.N)>>i])だったらそのまま返す if self.last_update[i][j]==self.lazy[(j+self.N)>>i]: return self.node[i][j] # そうでないとき,下にもぐって node[i][j] を求める self.node[i][j]=self.ope(self.get(i-1,j),self.get(i-1,j^(1<<(i-1)))) # node[i][j] は最新であることを記録する self.last_update[i][j]=self.lazy[(j+self.N)>>i] return self.node[i][j] def query(self,L,R,X): # A_{L^X}, A_{(L+1)^X}, ..., A_{(R-1)^X} についての答えを求める # 高々 2n 個のノードを見る res=self.E for i in range(self.n+1): if (L>>i)&1 and L+(1<<i)<=R: res=self.ope(res,self.get(i,L^X)) L+=1<<i for i in range(self.n,-1,-1): if L+(1<<i)<=R: res=self.ope(res,self.get(i,L^X)) L+=1<<i return res def op(L,R): res0=L[0]*pow11[R[1]]+R[0]*pow2[L[1]] res1=L[1]+R[1] return (res0%mod,res1) mod=998244353 n=int(input()) N=1<<n pow11=[1]*N pow2=[1]*N for i in range(1,N): pow11[i]=pow11[i-1]*11%mod pow2[i]=pow2[i-1]*2%mod S=input() seg=non_commutative_xor_segment_tree(n,[(int(S[i]),1) for i in range(1<<n)],op,(0,0)) q=int(input()) for _ in range(q): query=list(map(int,input().split())) if query[0]==1: x,y=query[1:] seg.update(x,(y,1)) else: L,R,X=query[1:] print(seg.query(L,R+1,X)[0])