''' mbinary ######################################################################### # File : winnerTree.py # Author: mbinary # Mail: zhuheqin1@gmail.com # Blog: https://mbinary.xyz # Github: https://github.com/mbinary # Created Time: 2018-05-19 23:06 # Description: ######################################################################### ''' class winnerTree: '''if i self.s else 2*p+self.lowExt-self.n+1 def arrayToTree(self, i): return (i+self.offset)//2 if i <= self.lowExt else (i-self.lowExt + self.n-1)//2 def win(self, a, b): return a < b if self.reverse else a > b def initTree(self, p): if p >= self.n: delta = p % 2 # !!! good job notice delta mark the lchild or rchlid return self.players[self.treeToArray(p//2)+delta] l = self.initTree(2*p) r = self.initTree(2*p+1) self.tree[p] = l if self.win(l, r) else r return self.tree[p] def winner(self): idx = 1 while 2*idx < self.n: idx = 2*idx if self.tree[2*idx] == self.tree[idx] else idx*2+1 num = self.treeToArray(idx) num = num+1 if self.players[num] != self.tree[1] else num return self.tree[1], num def getOppo(self, i, x, p): oppo = None if 2*p < self.n: oppo = self.tree[2*p] elif i <= self.lowExt: oppo = self.players[i-1+i % 2*2] else: lpl = self.players[2*p+self.lowExt-self.n+1] oppo = lpl if lpl != x else self.players[2*p+self.lowExt-self.n+2] return oppo def update(self, i, x): ''' i is 1-indexed which is the num of player and x is the new val of the player ''' self.players[i] = x p = self.arrayToTree(i) oppo = self.getOppo(i, x, p) self.tree[p] = x if self.win(x, oppo) else oppo p = p//2 while p: l = self.tree[p*2] r = None if 2*p+1 < self.n: r = self.tree[p*2+1] # notice this !!! else: r = self.players[2*p+self.lowExt-self.n+1] self.tree[p] = l if self.win(l, r) else r p = p//2 if __name__ == '__main__': s = [4, 1, 6, 7, 9, 5234, 0, 2, 7, 4, 123] t = winnerTree(s) print(t.players, t.tree) for i in s: val, idx = t.winner() print(val, idx) t.update(idx, -1) ''' [0, 4, 1, 6, 7, 9, 5234, 0, 2, 7, 4, 123] [0, 5234, 5234, 123, 7, 5234, 7, 123, 4, 7, 5234] 5234 6 123 11 9 5 7 4 7 9 6 3 4 1 4 10 2 8 1 2 '''