結果
問題 | No.1439 Let's Compare!!!! |
ユーザー |
|
提出日時 | 2022-06-09 00:30:36 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 14,165 bytes |
コンパイル時間 | 238 ms |
コンパイル使用メモリ | 82,284 KB |
実行使用メモリ | 127,704 KB |
最終ジャッジ日時 | 2024-09-21 05:19:27 |
合計ジャッジ時間 | 21,927 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 9 TLE * 8 |
ソースコード
#非再帰の平衡二分木import copyclass Node:"""ノードAttributes:key (any): ノードのキー。比較可能なものであれば良い。(1, 4)などタプルも可。val (any): ノードの値。lch (Node): 左の子ノード。rch (Node): 右の子ノード。bias (int): 平衡度。(左部分木の高さ)-(右部分木の高さ)。size (int): 自分を根とする部分木の大きさ"""def __init__(self, key, val):self.key = keyself.val = valself.lch = Noneself.rch = Noneself.bias = 0self.size = 1class AVLTree:"""非再帰AVL木Attributes:root (Node): 根ノード。初期値はNone。valdefault (any): ノード値のデフォルト値。デフォルトではNone。(数値、リストなど可)"""def __init__(self,valdefault=None):self.root = Noneself.valdefault = valdefaultdef rotate_left(self, v):u = v.rchu.size = v.sizev.size -= u.rch.size + 1 if u.rch is not None else 1v.rch = u.lchu.lch = vif u.bias == -1:u.bias = v.bias = 0else:u.bias = 1v.bias = -1return udef rotate_right(self, v):u = v.lchu.size = v.sizev.size -= u.lch.size + 1 if u.lch is not None else 1v.lch = u.rchu.rch = vif u.bias == 1:u.bias = v.bias = 0else:u.bias = -1v.bias = 1return udef rotateLR(self, v):u = v.lcht = u.rcht.size = v.sizev.size -= u.size - (t.rch.size if t.rch is not None else 0)u.size -= t.rch.size + 1 if t.rch is not None else 1u.rch = t.lcht.lch = uv.lch = t.rcht.rch = vself.update_bias_double(t)return tdef rotateRL(self, v):u = v.rcht = u.lcht.size = v.sizev.size -= u.size - (t.lch.size if t.lch is not None else 0)u.size -= t.lch.size + 1 if t.lch is not None else 1u.lch = t.rcht.rch = uv.rch = t.lcht.lch = vself.update_bias_double(t)return tdef update_bias_double(self, v):if v.bias == 1:v.rch.bias = -1v.lch.bias = 0elif v.bias == -1:v.rch.bias = 0v.lch.bias = 1else:v.rch.bias = 0v.lch.bias = 0v.bias = 0def insert(self, key, val=None):"""挿入指定したkeyを挿入する。valはkeyのノード値。Args:key (any): キー。val (any): 値。(指定しない場合はvaldefaultが入る)Note:同じキーがあった場合は上書きする。"""if val == None:val = copy.deepcopy(self.valdefault)if self.root is None:self.root = Node(key, val)returnv = self.roothistory = []while v is not None:if key < v.key:history.append((v, 1))v = v.lchelif v.key < key:history.append((v, -1))v = v.rchelif v.key == key:v.val = valreturnp, pdir = history[-1]if pdir == 1:p.lch = Node(key, val)else:p.rch = Node(key, val)while history:v, direction = history.pop()v.bias += directionv.size += 1new_v = Noneb = v.biasif b == 0:breakif b == 2:u = v.lchif u.bias == -1:new_v = self.rotateLR(v)else:new_v = self.rotate_right(v)breakif b == -2:u = v.rchif u.bias == 1:new_v = self.rotateRL(v)else:new_v = self.rotate_left(v)breakif new_v is not None:if len(history) == 0:self.root = new_vreturnp, pdir = history.pop()p.size += 1if pdir == 1:p.lch = new_velse:p.rch = new_vwhile history:p, pdir = history.pop()p.size += 1def delete(self, key):"""削除指定したkeyの要素を削除する。Args:key (any): キー。Return:bool: 指定したキーが存在するならTrue、しないならFalse。"""v = self.roothistory = []while v is not None:if key < v.key:history.append((v, 1))v = v.lchelif v.key < key:history.append((v, -1))v = v.rchelse:breakelse:return Falseif v.lch is not None:history.append((v, 1))lmax = v.lchwhile lmax.rch is not None:history.append((lmax, -1))lmax = lmax.rchv.key = lmax.keyv.val = lmax.valv = lmaxc = v.rch if v.lch is None else v.lchif history:p, pdir = history[-1]if pdir == 1:p.lch = celse:p.rch = celse:self.root = creturn Truewhile history:new_p = Nonep, pdir = history.pop()p.bias -= pdirp.size -= 1b = p.biasif b == 2:if p.lch.bias == -1:new_p = self.rotateLR(p)else:new_p = self.rotate_right(p)elif b == -2:if p.rch.bias == 1:new_p = self.rotateRL(p)else:new_p = self.rotate_left(p)elif b != 0:breakif new_p is not None:if len(history) == 0:self.root = new_preturn Truegp, gpdir = history[-1]if gpdir == 1:gp.lch = new_pelse:gp.rch = new_pif new_p.bias != 0:breakwhile history:p, pdir = history.pop()p.size -= 1return Truedef member(self, key):"""キーの存在チェック指定したkeyがあるかどうか判定する。Args:key (any): キー。Return:bool: 指定したキーが存在するならTrue、しないならFalse。"""v = self.rootwhile v is not None:if key < v.key:v = v.lchelif v.key < key:v = v.rchelse:return Truereturn Falsedef getval(self, key):"""値の取り出し指定したkeyの値を返す。Args:key (any): キー。Return:any: 指定したキーが存在するならそのオブジェクト。存在しなければvaldefault"""v = self.rootwhile v is not None:if key < v.key:v = v.lchelif v.key < key:v = v.rchelse:return v.valself.insert(key)return self[key] #def lower_bound(self, key):"""下限つき探索指定したkey以上で最小のキーを見つける。[key,inf)で最小Args:key (any): キーの下限。Return:any: 条件を満たすようなキー。そのようなキーが一つも存在しないならNone。"""ret = Nonev = self.rootwhile v is not None:if v.key >= key:if ret is None or ret > v.key:ret = v.keyv = v.lchelse:v = v.rchreturn retdef upper_bound(self, key):"""上限つき探索指定したkey未満で最大のキーを見つける。[-inf,key)で最大Args:key (any): キーの上限。Return:any: 条件を満たすようなキー。そのようなキーが一つも存在しないならNone。"""ret = Nonev = self.rootwhile v is not None:if v.key < key:if ret is None or ret < v.key:ret = v.keyv = v.rchelse:v = v.lchreturn retdef find_kth_element(self, k):"""小さい方からk番目の要素を見つけるArgs:k (int): 何番目の要素か(0オリジン)。Return:any: 小さい方からk番目のキーの値。"""v = self.roots = 0while v is not None:t = s+v.lch.size if v.lch is not None else sif t == k:return v.keyelif t < k:s = t+1v = v.rchelse:v = v.lchreturn Nonedef key_kth(self,key):'''Args:keyが何番目に小さい要素かを調べるReturn:int(keyが存在しなければNone)'''v = self.rootkth = 0f = Falsewhile v is not None:if key < v.key:v = v.lchelif v.key < key:kth += 1+v.lch.size if v.lch is not None else 1v = v.rchelse:kth += v.lch.size if v.lch is not None else 0f = Truebreakif f:return kthelse:return Nonedef getmin(self):'''Return:any: 存在するキーの最小値'''if len(self) == 0:raise('empty')ret = Nonev = self.rootwhile True:ret = vv = v.lchif v == None:breakreturn ret.keydef getmax(self):'''Return:any: 存在するキーの最大値'''if len(self) == 0:raise('empty')ret = Nonev = self.rootwhile True:ret = vv = v.rchif v == None:breakreturn ret.keydef popmin(self):'''存在するキーの最小値をpopするReturn:any: popした値'''if len(self) == 0:raise('empty')ret = Nonev = self.rootwhile True:ret = vv = v.lchif v == None:breakdel self[ret.key]return ret.keydef popmax(self):'''存在するキーの最大値をpopするReturn:any: popした値'''if len(self) == 0:raise('empty')ret = Nonev = self.rootwhile True:ret = vv = v.rchif v == None:breakdel self[ret.key]return ret.keydef popkth(self,k):'''存在するキーの小さい方からk番目をpopするReturn:any: popした値'''key = self.find_kth_element(k)del self[key]return keydef get_key_val(self):'''Return:dict: 存在するキーとノード値をdictで出力'''retdict = dict()for i in range(len(self)):key = self.find_kth_element(i)val = self[key]retdict[key] = valreturn retdictdef values(self):for i in range(len(self)):yield self[self.find_kth_element(i)]def keys(self):for i in range(len(self)):yield self.find_kth_element(i)def items(self):for i in range(len(self)):key = self.find_kth_element(i)yield key,self[key]def __iter__(self): return self.keys()def __contains__(self, key): return self.member(key)def __getitem__(self, key): return self.getval(key)def __setitem__(self, key, val): return self.insert(key, val)def __delitem__(self, key): return self.delete(key)def __bool__(self): return self.root is not Nonedef __len__(self): return self.root.size if self.root is not None else 0def __str__(self): return str(type(self))+'('+str(self.get_key_val())+')'def main():N = int(input())S = list(map(int,list(input())))T = list(map(int,list(input())))Q = int(input())SAVL = AVLTree()TAVL = AVLTree()SAVL.insert(N)TAVL.insert(N)for i in range(N):if S[i] > T[i]:SAVL.insert(i)elif S[i] < T[i]:TAVL.insert(i)for i in range(Q):c,x,y = input().split()x = int(x)-1y = int(y)if c == 'S':S[x] = yelse:T[x] = yif x in SAVL:SAVL.delete(x)elif x in TAVL:TAVL.delete(x)if S[x] > T[x]:SAVL.insert(x)elif S[x] < T[x]:TAVL.insert(x)s = SAVL.getmin()t = TAVL.getmin()if s == t == N:print('=')elif s < t:print('>')else:print('<')main()