結果
問題 | No.703 ゴミ拾い Easy |
ユーザー |
![]() |
提出日時 | 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 |
ソースコード
import sysreadline=sys.stdin.readlineclass 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=parentself.key=keyself.value=valueself.left=Noneself.right=Noneself.bias=0self.size=1class AVLTree_dict:def __init__(self):self.root=Nonedef Rotate_Left(self,node):node_right=node.rightnode_right.size=node.sizenode.size-=1if node_right.right!=None:node.size-=node_right.right.sizeif node_right.bias==-1:node_right.bias=0node.bias=0else:#assert node_right.bias==0node_right.bias=1node.bias=-1node.right=node_right.leftnode_right.left=nodereturn node_rightdef Rotate_Right(self,node):node_left=node.leftnode_left.size=node.sizenode.size-=1if node_left.left!=None:node.size-=node_left.left.sizeif node_left.bias==1:node_left.bias=0node.bias=0else:#assert node_left.bias==0node_left.bias=-1node.bias=1node.left=node_left.rightnode_left.right=nodereturn node_leftdef Rotate_Left_Right(self,node):node_left=node.leftnode_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.sizenode.size-=node_left.sizeif node_left_right.right!=None:node.size+=node_left_right.right.sizenode_left.size-=1if node_left_right.right!=None:node_left.size-=node_left_right.right.sizenode_left.right=node_left_right.leftnode_left_right.left=node_leftnode.left=node_left_right.rightnode_left_right.right=nodeself.Update_Bias_Double(node_left_right)return node_left_rightdef Rotate_Right_Left(self,node):node_right=node.rightnode_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.sizenode.size-=node_right.sizeif node_right_left.left!=None:node.size+=node_right_left.left.sizenode_right.size-=1if node_right_left.left!=None:node_right.size-=node_right_left.left.sizenode_right.left=node_right_left.rightnode_right_left.right=node_rightnode.right=node_right_left.leftnode_right_left.left=nodeself.Update_Bias_Double(node_right_left)return node_right_leftdef Update_Bias_Double(self,node):#assert node.right.bias*node.left.bias==-2#assert node.right.bias>0if node.bias==1:node.right.bias=-1node.left.bias=0elif node.bias==-1:node.right.bias=0node.left.bias=1else:node.right.bias=0node.left.bias=0node.bias=0def __getitem__(self,key):v=self.rootwhile v!=None:if key<v.key:v=v.leftelif v.key<key:v=v.rightelse:return v.valuereturn Nonedef __setitem__(self,key,value):if self.root==None:self.root=AVL_Node_dict(None,key,value)returnv=self.rootstack=[]while v!=None:if key<v.key:stack.append((v,1))v=v.leftelif v.key<key:stack.append((v,-1))v=v.rightelif v.key==key:v.value=valuereturnp,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+=directionv.size+=1vv=Noneif v.bias==2:if v.left.bias==-1:vv=self.Rotate_Left_Right(v)else:vv=self.Rotate_Right(v)#assert vv!=Nonebreakif v.bias==-2:if v.right.bias==1:vv=self.Rotate_Right_Left(v)else:vv=self.Rotate_Left(v)#assert vv!=Nonebreakif v.bias==0:breakif vv!=None:if len(stack)==0:self.root=vvreturnp,direction=stack.pop()p.size+=1if direction==1:p.left=vvelse:p.right=vvwhile stack:p,direction=stack.pop()p.size+=1def __delitem__(self,key):v=self.rootstack=[]while v!=None:if key<v.key:stack.append((v,1))v=v.leftelif v.key<key:stack.append((v,-1))v=v.rightelse:breakelse:return Falseif v.left!=None:stack.append((v,1))lmax=v.leftwhile lmax.right!=None:stack.append((lmax,-1))lmax=lmax.rightv.key=lmax.keyv.value=lmax.valuev=lmaxc=v.right if v.left==None else v.leftif stack:p,direction=stack[-1]if direction==1:p.left=celse:p.right=celse:self.root=creturn Truewhile stack:pp=Nonep,direction=stack.pop()p.bias-=directionp.size-=1if 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:breakif pp!=None:if len(stack)==0:self.root=ppreturn Truep,direction=stack[-1]if direction==1:p.left=ppelse:p.right=ppif pp.bias!=0:breakwhile stack:p,direction=stack.pop()p.size-=1return Truedef __contain__(self,key):v=self.rootwhile v!=None:if key<v.key:v=v.leftelif v.key<key:v=v.rightelse:return Truereturn Falsedef Bisect_Right(self,key):retu=Nonev=self.rootwhile v!=None:if v.key>key:if retu==None or retu[0]>v.key:retu=(v.key,v.value)v=v.leftelse:v=v.rightreturn retudef Bisect_Left(self,key):retu=Nonev=self.rootwhile v!=None:if v.key<key:if retu==None or retu[0]<v.key:retu=(v.key,v.value)v=v.rightelse:v=v.leftreturn retudef Find_Kth_Element(self,K):v=self.roots=0while v!=None:t=s+v.left.size if v.left!=None else sif t==K:return v.key,v.valueelif t<K:s=t+1v=v.rightelse:v=v.leftreturn Nonedef 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.keydef 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.valuedef 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!=Nonedef __len__(self):return 0 if self.root==None else self.root.sizedef __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 retuclass Convex_Hull_Trick:def __init__(self):self.lines=AVLTree_dict()def is_removed(self,line0,line1,line2):if line0==None:return Falseif line2==None:return Falsea0,b0=line0a1,b1=line1a2,b2=line2return (a1-a0)*(b2-b1)<=(b1-b0)*(a2-a1)def add_line(self,a,b):bb=self.lines[a]if bb!=None and bb<=b:returnline0=self.lines.Bisect_Left(a)line1=(a,b)line2=self.lines.Bisect_Right(a)if self.is_removed(line0,line1,line2):returnself.lines[a]=bline2=(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=line0line0=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=line2line2=None if line1==None else self.lines.Bisect_Right(line1[0])def __call__(self,x):size=len(self.lines)if not size:return Noneok,ng=-1,size-1while ng-ok>1:mid=(ok+ng)//2a0,b0=self.lines.Find_Kth_Element(mid)a1,b1=self.lines.Find_Kth_Element(mid+1)if a0*x+b0>a1*x+b1:ok=midelse:ng=mida,b=self.lines.Find_Kth_Element(ok+1)return a*x+bdef __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=0for i in range(N):dp.add_line(-2*X[i],cost+X[i]**2+Y[i]**2)cost=dp(A[i])+A[i]**2ans=costprint(ans)