結果
問題 | No.1375 Divide and Update |
ユーザー | あかしあみどり |
提出日時 | 2023-02-28 18:19:00 |
言語 | PyPy3 (7.3.15) |
結果 |
WA
|
実行時間 | - |
コード長 | 5,376 bytes |
コンパイル時間 | 1,197 ms |
コンパイル使用メモリ | 82,240 KB |
実行使用メモリ | 166,064 KB |
最終ジャッジ日時 | 2024-09-15 20:52:09 |
合計ジャッジ時間 | 6,402 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 41 ms
53,248 KB |
testcase_01 | AC | 41 ms
52,992 KB |
testcase_02 | AC | 40 ms
53,248 KB |
testcase_03 | WA | - |
testcase_04 | RE | - |
testcase_05 | RE | - |
testcase_06 | RE | - |
testcase_07 | RE | - |
testcase_08 | WA | - |
testcase_09 | RE | - |
testcase_10 | RE | - |
testcase_11 | RE | - |
testcase_12 | RE | - |
testcase_13 | WA | - |
testcase_14 | RE | - |
testcase_15 | RE | - |
testcase_16 | RE | - |
testcase_17 | RE | - |
testcase_18 | RE | - |
testcase_19 | RE | - |
testcase_20 | RE | - |
ソースコード
def oi(): return int(input()) def os(): return input() def mi(): return list(map(int, input().split())) # import sys # input = sys.stdin.readline # import sys # sys.setrecursionlimit(10**8) # import pypyjit # pypyjit.set_param('max_unroll_recursion=-1') input_count = 0 input_count = 0 N,X,Y = mi() A = mi() #####segfunc##### def segfunc(x, y): return max(x,y) ################# #####segfunc##### def segfunc2(x, y): return min(x,y) ################# #####ide_ele##### ide_ele = 0 ################# class SegTree: """ init(init_val, ide_ele): 配列init_valで初期化 O(N) update(k, x): k番目の値をxに更新 O(logN) query(l, r): 区間[l, r)をsegfuncしたものを返す O(logN) """ def __init__(self, init_val, segfunc, ide_ele): """ init_val: 配列の初期値 segfunc: 区間にしたい操作 ide_ele: 単位元 n: 要素数 num: n以上の最小の2のべき乗 tree: セグメント木(1-index) """ self.n = len(init_val) self.bitlen = (self.n - 1).bit_length() self.segfunc = segfunc self.ide_ele = ide_ele self.num = 1 << self.bitlen self.tree = [ide_ele] * 2 * self.num # 配列の値を葉にセット for i in range(self.n): self.tree[self.num + i] = init_val[i] # 構築していく for i in range(self.num - 1, 0, -1): self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1]) def update(self, k, x): """ k番目の値をxに更新 k: index(0-index) x: update value """ k += self.num self.tree[k] = x while k > 1: self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1]) k >>= 1 def query(self, l, r): """ [l, r)のsegfuncしたものを得る l: index(0-index) r: index(0-index) """ res = self.ide_ele l += self.num r += self.num while l < r: if l & 1: res = self.segfunc(res, self.tree[l]) l += 1 if r & 1: res = self.segfunc(res, self.tree[r - 1]) l >>= 1 r >>= 1 return res # (累積がx以上のうち最も小さい値, その時のindex)を得る # x以上のものが無ければ None を返す def ge(self, x): bits = 1 base = self.ide_ele if self.tree[1] < x: return (None, None) for i in range(self.bitlen): bits <<= 1 ne = self.segfunc(self.tree[bits], base) #左側のノードまでの累積を計算 if ne < x: base = ne # 右側のノードに進むなら左側までの累積を保存 bits += 1 ind = bits - self.num v = self.tree[bits] return ind, v # (累積がxを超える値のうち最も小さい値, その時のindex)を得る # xを超えるものが無ければ None を返す def gt(self, x): return self.ge(x+1) # (累積がx以下のうち最も大きい値, その時のindex)を得る # x以下のものが無ければ None を返す def le(self, x): if self.tree[self.num] > x: return (None, None) if self.tree[1] < x: return self.n-1, self.tree[self.num-self.n-1] bits = 1 base = self.ide_ele for i in range(self.bitlen): bits <<= 1 ne = self.segfunc(self.tree[bits], base) #左側のノードまでの累積を計算 if ne < x: base = ne # 右側のノードに進むなら左側までの累積を保存 bits += 1 ind = bits - self.num v = self.tree[bits] if self.segfunc(base, v) == x: return ind, v return ind-1, self.tree[self.num - (ind-1)] def lt(self, x): return self.le(x-1) import itertools as it RA = A[::-1] X_acc = list(it.accumulate([X-a for a in A])) X_max_tree = SegTree(list(it.accumulate([X-a for a in A])), segfunc, -1*float("inf")) X_min_tree = SegTree(list(it.accumulate([X-a for a in A])), segfunc2, 0) sumA = sum(A) X_max = [0,-1] X_min = [0,-1] out = [sumA]*(N-2) for i in range(2,N): if X_acc[i-2] > X_max[0]: X_max[0] = X_acc[i-2] X_max[1] = i-2 if X_acc[i-2] < X_min[0]: X_min[0] = X_acc[i-2] X_min[i] = i-2 a = X_max_tree.query(X_min[1]+1, i-1) - X_min[0] c = X_max[0] - X_min_tree.query(0,X_max[1]+1) # print((b,Y_min), d) out[i-2] += max(a,c) import bisect Y_max_tree = SegTree(list(it.accumulate([Y-a for a in RA[:-2]])), segfunc, -1*float("inf")) Y_min_tree = SegTree(list(it.accumulate([Y-a for a in RA[:-2]])), segfunc2, 0) Y_acc = list(it.accumulate([Y-a for a in RA[:-2]])) Y_dict = {} for i,y in enumerate(Y_acc): if y in Y_dict: Y_dict[y].append(i) else: Y_dict[y] = [i] for i in range(N-2): b = Y_max_tree.query(0, N-i-2) ind = bisect.bisect_right(Y_dict[b], i) b_min = Y_min_tree.query(i,ind) d = Y_min_tree.query(0, N-i-2) ind = bisect.bisect_left(Y_dict[d], i) d_max = Y_max_tree.query(ind, N-i-2) # print(b, b_min, d, d_max, ind,N-i-2) out[i] += max(b-b_min, d_max-d) print(*out, sep="\n")