結果

問題 No.2169 To Arithmetic
ユーザー lam6er
提出日時 2025-03-26 16:00:00
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 1,486 ms / 2,000 ms
コード長 4,037 bytes
コンパイル時間 311 ms
コンパイル使用メモリ 82,292 KB
実行使用メモリ 143,508 KB
最終ジャッジ日時 2025-03-26 16:00:58
合計ジャッジ時間 15,141 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 25
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

import bisect
def main():
import sys
input = sys.stdin.read
data = input().split()
idx = 0
N = int(data[idx])
idx += 1
Q = int(data[idx])
idx += 1
A = list(map(int, data[idx:idx+N]))
idx += N
queries = list(map(int, data[idx:idx+Q]))
# Compute B array and sorted B with prefix sum
B = []
for j in range(1, N):
B.append(A[j] - A[j-1])
B.sort()
prefix_sum = [0] * (len(B) + 1)
for i in range(len(B)):
prefix_sum[i+1] = prefix_sum[i] + B[i]
# Li Chao Tree implementation
class Line:
__slots__ = ['a', 'b']
def __init__(self, a, b):
self.a = a
self.b = b
def value(self, x):
return self.a * x + self.b
class LiChaoNode:
__slots__ = ['line', 'left', 'right', 'l', 'r']
def __init__(self, l, r):
self.line = None
self.left = None
self.right = None
self.l = l
self.r = r
class LiChaoTree:
def __init__(self, x_min, x_max):
self.root = LiChaoNode(x_min, x_max)
def insert_line(self, new_line):
node = self.root
while True:
l = node.l
r = node.r
m = (l + r) // 2
if node.line is None:
node.line = new_line
break
curr_line = node.line
curr_l = curr_line.value(l)
new_l = new_line.value(l)
curr_r = curr_line.value(r)
new_r = new_line.value(r)
if new_l > curr_l and new_r > curr_r:
node.line = new_line
break
if new_l <= curr_l and new_r <= curr_r:
break
curr_m = curr_line.value(m)
new_m = new_line.value(m)
if new_m > curr_m:
node.line, new_line = new_line, curr_line
# After swap, re-evaluate
curr_line = node.line
curr_l = curr_line.value(l)
new_l = new_line.value(l)
curr_r = curr_line.value(r)
new_r = new_line.value(r)
curr_m = curr_line.value(m)
new_m = new_line.value(m)
# Determine which child to go into
if new_l > curr_l:
if not node.left:
node.left = LiChaoNode(l, m)
node = node.left
else:
if not node.right:
node.right = LiChaoNode(m+1, r)
node = node.right
def query_max(self, x):
res = -float('inf')
node = self.root
while node:
if node.line:
current_val = node.line.value(x)
if current_val > res:
res = current_val
if node.l == node.r:
break
m = (node.l + node.r) // 2
if x <= m:
node = node.left
else:
node = node.right
return res
# Initialize Li Chao Tree
x_min = -10**18
x_max = 10**18
tree = LiChaoTree(x_min, x_max)
for j in range(N):
a = -j # since x is j (0-based), line is y = -j*d + A[j]
b = A[j]
line = Line(a, b)
tree.insert_line(line)
# Process queries
A1 = A[0]
output = []
for d in queries:
# Compute sum_part
k = bisect.bisect_right(B, d)
sum_d = d * k - prefix_sum[k]
# Compute max_val
max_k = tree.query_max(d)
max_val = max_k - A1
L = max(0, max_val)
ans = L + sum_d
output.append(ans)
print('\n'.join(map(str, output)))
if __name__ == "__main__":
main()
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0