結果
| 問題 |
No.2332 Make a Sequence
|
| コンテスト | |
| ユーザー |
vwxyz
|
| 提出日時 | 2023-08-10 18:40:18 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 989 ms / 2,000 ms |
| コード長 | 3,342 bytes |
| コンパイル時間 | 580 ms |
| コンパイル使用メモリ | 82,432 KB |
| 実行使用メモリ | 175,232 KB |
| 最終ジャッジ日時 | 2024-11-17 03:28:36 |
| 合計ジャッジ時間 | 34,940 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 61 |
ソースコード
import sys
readline=sys.stdin.readline
class Li_Chao_Tree:
def __init__(self,N,X=None,inf=float("inf")):
self.N=N
if X==None:
self.X=[x for x in range(self.N)]
else:
self.X=X
self.idx={x:i for i,x in enumerate(self.X)}
self.inf=inf
self.li_chao_tree=[(0,self.inf)]*(2*self.N)
self.left,self.right=[None]*2*N,[None]*2*N
for i in range(self.N,2*self.N):
self.left[i]=self.X[i-self.N]
self.right[i]=self.X[i-self.N]
for i in range(self.N-1,0,-1):
self.left[i]=self.left[i<<1]
self.right[i]=self.right[i<<1|1]
def add_line_one_segment(self,a,b,i):
queue=[i]
while queue:
i=queue.pop()
aa,bb=self.li_chao_tree[i]
l=a*self.X[self.left[i]]+b
r=a*self.X[self.right[i]]+b
ll=aa*self.X[self.left[i]]+bb
rr=aa*self.X[self.right[i]]+bb
if ll<=l and rr<=r:
continue
if l<=ll and r<=rr:
self.li_chao_tree[i]=(a,b)
continue
queue.append(i<<1)
queue.append(i<<1|1)
def add_line(self,a,b,L=None,R=None):
if L==None:
L=self.N
else:
L+=self.N
if R==None:
R=2*self.N
else:
R+=self.N
while L<R:
if L%2:
self.add_line_one_segment(a,b,L)
L+=1
if R%2:
R-=1
self.add_line_one_segment(a,b,R)
L>>=1
R>>=1
def __call__(self,x):
i=self.idx[x]+self.N
retu=self.inf
while i:
a,b=self.li_chao_tree[i]
retu=min(retu,a*x+b)
i>>=1
return retu
def __getitem__(self,i):
x=self.X[i]
i+=self.N
retu=self.inf
while i:
a,b=self.li_chao_tree[i]
retu=min(retu,a*x+b)
i>>=1
return retu
def __str__(self):
li_chao_tree=[(0,inf)]*self.N
for i,x in enumerate(self.X):
ii=i+self.N
while ii:
aa,bb=self.li_chao_tree[ii]
a,b=li_chao_tree[i]
if aa*x+bb<a*x+b:
li_chao_tree[i]=aa,bb
ii>>=1
return "["+", ".join(map(str,li_chao_tree))+"]"
def Z_algorithm(lst):
le=len(lst)
LCP=[None]*le
LCP[0]=le
L,R=0,0
for i in range(1,le):
if i<R:
x=LCP[i-L]
if x<R-i:
LCP[i]=x
elif R-i<x:
LCP[i]=R-i
else:
while R<le and lst[R-i]==lst[R]:
R+=1
LCP[i]=R-i
L=i
else:
R=max(R,i)
while R<le and lst[R-i]==lst[R]:
R+=1
LCP[i]=R-i
L=i
return LCP
N,M=map(int,readline().split())
A=list(map(int,readline().split()))
B=list(map(int,readline().split()))
C=list(map(int,readline().split()))
Z=Z_algorithm(A+B)
inf=1<<60
LCT=Li_Chao_Tree(M+1,inf=inf)
dp=[inf]*(M+1)
dp[0]=0
for m in range(M):
k=Z[N+m]
LCT.add_line(C[m],dp[m]-m*C[m],m,m+k+1)
dp[m+1]=LCT[m+1]
if dp[M]==inf:
ans=-1
else:
ans=dp[M]
print(ans)
vwxyz