結果
問題 | No.2686 商品券の使い道 |
ユーザー | LyricalMaestro |
提出日時 | 2024-10-30 01:57:29 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 378 ms / 3,000 ms |
コード長 | 4,566 bytes |
コンパイル時間 | 328 ms |
コンパイル使用メモリ | 82,312 KB |
実行使用メモリ | 98,084 KB |
最終ジャッジ日時 | 2024-10-30 01:57:41 |
合計ジャッジ時間 | 11,795 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 38 ms
54,100 KB |
testcase_01 | AC | 37 ms
53,508 KB |
testcase_02 | AC | 75 ms
75,828 KB |
testcase_03 | AC | 82 ms
76,168 KB |
testcase_04 | AC | 76 ms
75,968 KB |
testcase_05 | AC | 77 ms
76,028 KB |
testcase_06 | AC | 75 ms
76,180 KB |
testcase_07 | AC | 76 ms
75,700 KB |
testcase_08 | AC | 74 ms
75,792 KB |
testcase_09 | AC | 75 ms
75,780 KB |
testcase_10 | AC | 76 ms
75,944 KB |
testcase_11 | AC | 188 ms
83,372 KB |
testcase_12 | AC | 132 ms
78,476 KB |
testcase_13 | AC | 167 ms
82,924 KB |
testcase_14 | AC | 187 ms
81,752 KB |
testcase_15 | AC | 173 ms
81,596 KB |
testcase_16 | AC | 183 ms
83,524 KB |
testcase_17 | AC | 166 ms
80,716 KB |
testcase_18 | AC | 161 ms
82,068 KB |
testcase_19 | AC | 156 ms
81,488 KB |
testcase_20 | AC | 156 ms
82,692 KB |
testcase_21 | AC | 186 ms
83,092 KB |
testcase_22 | AC | 145 ms
79,584 KB |
testcase_23 | AC | 111 ms
77,536 KB |
testcase_24 | AC | 183 ms
82,396 KB |
testcase_25 | AC | 116 ms
78,652 KB |
testcase_26 | AC | 160 ms
81,200 KB |
testcase_27 | AC | 164 ms
82,324 KB |
testcase_28 | AC | 84 ms
76,664 KB |
testcase_29 | AC | 192 ms
80,636 KB |
testcase_30 | AC | 282 ms
95,300 KB |
testcase_31 | AC | 314 ms
92,236 KB |
testcase_32 | AC | 332 ms
97,052 KB |
testcase_33 | AC | 293 ms
95,448 KB |
testcase_34 | AC | 191 ms
80,796 KB |
testcase_35 | AC | 282 ms
93,340 KB |
testcase_36 | AC | 335 ms
98,040 KB |
testcase_37 | AC | 368 ms
97,712 KB |
testcase_38 | AC | 320 ms
95,432 KB |
testcase_39 | AC | 333 ms
96,172 KB |
testcase_40 | AC | 334 ms
94,260 KB |
testcase_41 | AC | 143 ms
77,756 KB |
testcase_42 | AC | 378 ms
97,168 KB |
testcase_43 | AC | 350 ms
97,696 KB |
testcase_44 | AC | 351 ms
97,480 KB |
testcase_45 | AC | 323 ms
95,428 KB |
testcase_46 | AC | 359 ms
98,084 KB |
evil_random20_1.txt | AC | 102 ms
76,188 KB |
evil_random20_2.txt | AC | 107 ms
76,488 KB |
evil_random20_3.txt | AC | 103 ms
76,400 KB |
ソースコード
## https://yukicoder.me/problems/no/2686 class SegmentTree: """ 非再帰版セグメント木。 更新は「加法」、取得は「最大値」のもの限定。 """ def __init__(self, init_array): n = 1 while n < len(init_array): n *= 2 self.size = n self.array = [[] for _ in range(2 * self.size)] for i, q_array in enumerate(init_array): self.array[self.size + i] = q_array end_index = self.size start_index = end_index // 2 while start_index >= 1: for i in range(start_index, end_index): self.array[i] = self._fill(self.array[2 * i], self.array[2 * i + 1]) end_index = start_index start_index = end_index // 2 def _fill(self, left, right): q_map = {} for l, v in left: q_map[l]= v for r, v in right: if r not in q_map: q_map[r] = 0 q_map[r] = max(v, q_map[r]) q_array = [(q, v) for q, v in q_map.items() ] q_array.sort(key=lambda x : x[0]) return q_array def add(self, x, a): index = self.size + x self.array[index] += a while index > 1: index //= 2 self.array[index] = max(self.array[2 * index], self.array[2 * index + 1]) def find(self, array, q): if len(array) == 0: return 0 if array[0][0] > q: return 0 low = 0 high = len(array) - 1 while high - low > 1: mid = (high + low) // 2 if array[mid][0] <= q: low = mid else: high = mid if array[high][0] <= q: return array[high][1] else: return array[low][1] def get_max(self, l, r, q): L = self.size + l; R = self.size + r # 2. 区間[l, r)の最大値を求める s = 0 while L < R: if R & 1: R -= 1 s = max(s, self.find(self.array[R], q)) if L & 1: s = max(s, self.find(self.array[L], q)) L += 1 L >>= 1; R >>= 1 return s def solve(N, M, Q, ab): if N == 1: A, B = ab[0] if A <= M and B <= Q: return A + B else: return 0 n1 = N // 2 n2 = N - n1 # n1の全列挙 n1_array = [] for bit3 in range(3 ** n1): p = 0 q = 0 value = 0 for i in range(n1): a = bit3 % 3 if a == 1: p += ab[i][0] value += ab[i][1] elif a == 2: q += ab[i][0] value += ab[i][1] bit3 //= 3 if p <= M and q <= Q: n1_array.append((p, q, value)) # n2の方をseqmenttreeに格納する p_q_map = {} for bit3 in range(3 ** n2): p = 0 q = 0 value = 0 for i in range(n2): a = bit3 % 3 if a == 1: p += ab[n1 + i][0] value += ab[n1 + i][1] elif a == 2: q += ab[n1 + i][0] value += ab[n1 + i][1] bit3 //= 3 if p <= M and q <= Q: if p not in p_q_map: p_q_map[p] = {} if q not in p_q_map[p]: p_q_map[p][q] = -1 p_q_map[p][q] = max(p_q_map[p][q], value) # Pについての座標圧縮 p_set = set() for p, _, _ in n1_array: p_set.add(M - p) for p in p_q_map.keys(): p_set.add(p) p_list = list(p_set) p_list.sort() p_map = {} for i, p in enumerate(p_list): p_map[p] = i # SegmentTree構築s p_q_array = [[] for _ in range(len(p_list)) ] for p, q_map in p_q_map.items(): q_array = [ (q, v) for q, v in q_map.items() ] q_array.sort(key=lambda x: x[0]) p_q_array[p_map[p]] = q_array # SegmentTree seg_tree = SegmentTree(p_q_array) answer= 0 for p, q, v in n1_array: max_value = seg_tree.get_max(0, p_map[M - p] + 1, Q - q) ans = v + max_value answer = max(ans, answer) return answer def main(): N, M, Q = map(int, input().split()) ab = [] for _ in range(N): A, B = map(int, input().split()) ab.append((A, B)) ans = solve(N, M, Q, ab) print(ans) if __name__ == "__main__": main()