結果

問題 No.703 ゴミ拾い Easy
ユーザー vwxyz
提出日時 2023-01-03 17:45:25
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 1,455 ms / 1,500 ms
コード長 12,201 bytes
コンパイル時間 366 ms
コンパイル使用メモリ 82,432 KB
実行使用メモリ 164,540 KB
最終ジャッジ日時 2024-11-27 02:19:57
合計ジャッジ時間 22,607 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 46
権限があれば一括ダウンロードができます

ソースコード

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

import sys
readline=sys.stdin.readline
class AVL_Node_dict:
"""
Attributes:
key (any): (1, 4)
val (any):
left (Node):
right (Node):
bias (int): ()-()
size (int):
"""
def __init__(self,parent,key,value):
self.parent=parent
self.key=key
self.value=value
self.left=None
self.right=None
self.bias=0
self.size=1
class AVLTree_dict:
def __init__(self):
self.root=None
def Rotate_Left(self,node):
node_right=node.right
node_right.size=node.size
node.size-=1
if node_right.right!=None:
node.size-=node_right.right.size
if node_right.bias==-1:
node_right.bias=0
node.bias=0
else:
#assert node_right.bias==0
node_right.bias=1
node.bias=-1
node.right=node_right.left
node_right.left=node
return node_right
def Rotate_Right(self,node):
node_left=node.left
node_left.size=node.size
node.size-=1
if node_left.left!=None:
node.size-=node_left.left.size
if node_left.bias==1:
node_left.bias=0
node.bias=0
else:
#assert node_left.bias==0
node_left.bias=-1
node.bias=1
node.left=node_left.right
node_left.right=node
return node_left
def Rotate_Left_Right(self,node):
node_left=node.left
node_left_right=node_left.right
#assert node.bias==2
#assert node_left.bias==-1
#assert node_left_right.bias in (-1,0,1)
node_left_right.size=node.size
node.size-=node_left.size
if node_left_right.right!=None:
node.size+=node_left_right.right.size
node_left.size-=1
if node_left_right.right!=None:
node_left.size-=node_left_right.right.size
node_left.right=node_left_right.left
node_left_right.left=node_left
node.left=node_left_right.right
node_left_right.right=node
self.Update_Bias_Double(node_left_right)
return node_left_right
def Rotate_Right_Left(self,node):
node_right=node.right
node_right_left=node_right.left
#assert node.bias==-2
#assert node_right.bias==1
#assert node_right_left.bias in (-1,0,1)
node_right_left.size=node.size
node.size-=node_right.size
if node_right_left.left!=None:
node.size+=node_right_left.left.size
node_right.size-=1
if node_right_left.left!=None:
node_right.size-=node_right_left.left.size
node_right.left=node_right_left.right
node_right_left.right=node_right
node.right=node_right_left.left
node_right_left.left=node
self.Update_Bias_Double(node_right_left)
return node_right_left
def Update_Bias_Double(self,node):
#assert node.right.bias*node.left.bias==-2
#assert node.right.bias>0
if node.bias==1:
node.right.bias=-1
node.left.bias=0
elif node.bias==-1:
node.right.bias=0
node.left.bias=1
else:
node.right.bias=0
node.left.bias=0
node.bias=0
def __getitem__(self,key):
v=self.root
while v!=None:
if key<v.key:
v=v.left
elif v.key<key:
v=v.right
else:
return v.value
return None
def __setitem__(self,key,value):
if self.root==None:
self.root=AVL_Node_dict(None,key,value)
return
v=self.root
stack=[]
while v!=None:
if key<v.key:
stack.append((v,1))
v=v.left
elif v.key<key:
stack.append((v,-1))
v=v.right
elif v.key==key:
v.value=value
return
p,direction=stack[-1]
if direction==1:
p.left=AVL_Node_dict(p,key,value)
else:
p.right=AVL_Node_dict(p,key,value)
while stack:
v,direction=stack.pop()
v.bias+=direction
v.size+=1
vv=None
if v.bias==2:
if v.left.bias==-1:
vv=self.Rotate_Left_Right(v)
else:
vv=self.Rotate_Right(v)
#assert vv!=None
break
if v.bias==-2:
if v.right.bias==1:
vv=self.Rotate_Right_Left(v)
else:
vv=self.Rotate_Left(v)
#assert vv!=None
break
if v.bias==0:
break
if vv!=None:
if len(stack)==0:
self.root=vv
return
p,direction=stack.pop()
p.size+=1
if direction==1:
p.left=vv
else:
p.right=vv
while stack:
p,direction=stack.pop()
p.size+=1
def __delitem__(self,key):
v=self.root
stack=[]
while v!=None:
if key<v.key:
stack.append((v,1))
v=v.left
elif v.key<key:
stack.append((v,-1))
v=v.right
else:
break
else:
return False
if v.left!=None:
stack.append((v,1))
lmax=v.left
while lmax.right!=None:
stack.append((lmax,-1))
lmax=lmax.right
v.key=lmax.key
v.value=lmax.value
v=lmax
c=v.right if v.left==None else v.left
if stack:
p,direction=stack[-1]
if direction==1:
p.left=c
else:
p.right=c
else:
self.root=c
return True
while stack:
pp=None
p,direction=stack.pop()
p.bias-=direction
p.size-=1
if p.bias==2:
if p.left.bias==-1:
pp=self.Rotate_Left_Right(p)
else:
pp=self.Rotate_Right(p)
elif p.bias==-2:
if p.right.bias==1:
pp=self.Rotate_Right_Left(p)
else:
pp=self.Rotate_Left(p)
elif p.bias!=0:
break
if pp!=None:
if len(stack)==0:
self.root=pp
return True
p,direction=stack[-1]
if direction==1:
p.left=pp
else:
p.right=pp
if pp.bias!=0:
break
while stack:
p,direction=stack.pop()
p.size-=1
return True
def __contain__(self,key):
v=self.root
while v!=None:
if key<v.key:
v=v.left
elif v.key<key:
v=v.right
else:
return True
return False
def Bisect_Right(self,key):
retu=None
v=self.root
while v!=None:
if v.key>key:
if retu==None or retu[0]>v.key:
retu=(v.key,v.value)
v=v.left
else:
v=v.right
return retu
def Bisect_Left(self,key):
retu=None
v=self.root
while v!=None:
if v.key<key:
if retu==None or retu[0]<v.key:
retu=(v.key,v.value)
v=v.right
else:
v=v.left
return retu
def Find_Kth_Element(self,K):
v=self.root
s=0
while v!=None:
t=s+v.left.size if v.left!=None else s
if t==K:
return v.key,v.value
elif t<K:
s=t+1
v=v.right
else:
v=v.left
return None
def keys(self):
stack=[(self.root,True)]
while stack:
node,subtree=stack.pop()
if subtree:
if node.right!=None:
stack.append((node.right,True))
stack.append((node,False))
if node.left!=None:
stack.append((node.left,True))
else:
yield node.key
def values(self):
stack=[(self.root,True)]
while stack:
node,subtree=stack.pop()
if subtree:
if node.right!=None:
stack.append((node.right,True))
stack.append((node,False))
if node.left!=None:
stack.append((node.left,True))
else:
yield node.value
def items(self):
stack=[(self.root,True)]
while stack:
node,subtree=stack.pop()
if subtree:
if node.right!=None:
stack.append((node.right,True))
stack.append((node,False))
if node.left!=None:
stack.append((node.left,True))
else:
yield (node.key,node.value)
def __bool__(self):
return self.root!=None
def __len__(self):
return 0 if self.root==None else self.root.size
def __iter__(self):
return iter(self.keys())
def __str__(self):
if self.root==None:
retu="{}"
else:
retu="{"+", ".join(f"{r}: {m}" for r,m in self.items())+"}"
return retu
class Convex_Hull_Trick:
def __init__(self):
self.lines=AVLTree_dict()
def is_removed(self,line0,line1,line2):
if line0==None:
return False
if line2==None:
return False
a0,b0=line0
a1,b1=line1
a2,b2=line2
return (a1-a0)*(b2-b1)<=(b1-b0)*(a2-a1)
def add_line(self,a,b):
bb=self.lines[a]
if bb!=None and bb<=b:
return
line0=self.lines.Bisect_Left(a)
line1=(a,b)
line2=self.lines.Bisect_Right(a)
if self.is_removed(line0,line1,line2):
return
self.lines[a]=b
line2=(a,b)
line1=self.lines.Bisect_Left(line2[0])
line0=None if line1==None else self.lines.Bisect_Left(line1[0])
while self.is_removed(line0,line1,line2):
del self.lines[line1[0]]
line1=line0
line0=None if line1==None else self.lines.Bisect_Left(line1[0])
line0=(a,b)
line1=self.lines.Bisect_Right(line0[0])
line2=None if line1==None else self.lines.Bisect_Right(line1[0])
while self.is_removed(line0,line1,line2):
del self.lines[line1[0]]
line1=line2
line2=None if line1==None else self.lines.Bisect_Right(line1[0])
def __call__(self,x):
size=len(self.lines)
if not size:
return None
ok,ng=-1,size-1
while ng-ok>1:
mid=(ok+ng)//2
a0,b0=self.lines.Find_Kth_Element(mid)
a1,b1=self.lines.Find_Kth_Element(mid+1)
if a0*x+b0>a1*x+b1:
ok=mid
else:
ng=mid
a,b=self.lines.Find_Kth_Element(ok+1)
return a*x+b
def __getitem__(self,a):
return self.lines[a]
def __setitem__(self,a,b):
self.add_line(a,b)
N=int(readline())
A=list(map(int,readline().split()))
X=list(map(int,readline().split()))
Y=list(map(int,readline().split()))
dp=Convex_Hull_Trick()
cost=0
for i in range(N):
dp.add_line(-2*X[i],cost+X[i]**2+Y[i]**2)
cost=dp(A[i])+A[i]**2
ans=cost
print(ans)
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0