結果
問題 | No.2332 Make a Sequence |
ユーザー | navel_tos |
提出日時 | 2024-02-25 21:44:33 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,092 ms / 2,000 ms |
コード長 | 4,212 bytes |
コンパイル時間 | 299 ms |
コンパイル使用メモリ | 81,792 KB |
実行使用メモリ | 225,252 KB |
最終ジャッジ日時 | 2024-09-29 11:19:51 |
合計ジャッジ時間 | 33,978 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 41 ms
52,352 KB |
testcase_01 | AC | 42 ms
52,736 KB |
testcase_02 | AC | 42 ms
52,736 KB |
testcase_03 | AC | 41 ms
52,480 KB |
testcase_04 | AC | 41 ms
52,736 KB |
testcase_05 | AC | 41 ms
52,480 KB |
testcase_06 | AC | 42 ms
52,480 KB |
testcase_07 | AC | 334 ms
205,512 KB |
testcase_08 | AC | 114 ms
103,644 KB |
testcase_09 | AC | 241 ms
148,104 KB |
testcase_10 | AC | 305 ms
181,400 KB |
testcase_11 | AC | 226 ms
150,416 KB |
testcase_12 | AC | 351 ms
224,928 KB |
testcase_13 | AC | 352 ms
224,932 KB |
testcase_14 | AC | 363 ms
225,156 KB |
testcase_15 | AC | 356 ms
225,156 KB |
testcase_16 | AC | 346 ms
225,252 KB |
testcase_17 | AC | 341 ms
225,128 KB |
testcase_18 | AC | 346 ms
225,056 KB |
testcase_19 | AC | 345 ms
224,976 KB |
testcase_20 | AC | 347 ms
224,876 KB |
testcase_21 | AC | 342 ms
224,988 KB |
testcase_22 | AC | 358 ms
223,564 KB |
testcase_23 | AC | 365 ms
223,320 KB |
testcase_24 | AC | 360 ms
223,904 KB |
testcase_25 | AC | 359 ms
223,512 KB |
testcase_26 | AC | 368 ms
223,344 KB |
testcase_27 | AC | 388 ms
222,584 KB |
testcase_28 | AC | 385 ms
223,004 KB |
testcase_29 | AC | 388 ms
223,144 KB |
testcase_30 | AC | 382 ms
223,452 KB |
testcase_31 | AC | 406 ms
222,844 KB |
testcase_32 | AC | 429 ms
221,256 KB |
testcase_33 | AC | 426 ms
221,480 KB |
testcase_34 | AC | 424 ms
221,480 KB |
testcase_35 | AC | 410 ms
221,436 KB |
testcase_36 | AC | 419 ms
221,732 KB |
testcase_37 | AC | 408 ms
208,528 KB |
testcase_38 | AC | 407 ms
220,568 KB |
testcase_39 | AC | 424 ms
220,700 KB |
testcase_40 | AC | 424 ms
220,312 KB |
testcase_41 | AC | 408 ms
221,112 KB |
testcase_42 | AC | 600 ms
178,192 KB |
testcase_43 | AC | 588 ms
177,552 KB |
testcase_44 | AC | 523 ms
177,564 KB |
testcase_45 | AC | 519 ms
186,352 KB |
testcase_46 | AC | 645 ms
177,556 KB |
testcase_47 | AC | 1,047 ms
205,972 KB |
testcase_48 | AC | 1,092 ms
206,096 KB |
testcase_49 | AC | 1,033 ms
205,716 KB |
testcase_50 | AC | 993 ms
205,844 KB |
testcase_51 | AC | 1,073 ms
205,848 KB |
testcase_52 | AC | 411 ms
222,424 KB |
testcase_53 | AC | 404 ms
222,856 KB |
testcase_54 | AC | 408 ms
222,488 KB |
testcase_55 | AC | 390 ms
222,612 KB |
testcase_56 | AC | 388 ms
222,516 KB |
testcase_57 | AC | 358 ms
223,336 KB |
testcase_58 | AC | 337 ms
223,156 KB |
testcase_59 | AC | 343 ms
222,572 KB |
testcase_60 | AC | 346 ms
222,356 KB |
testcase_61 | AC | 339 ms
222,148 KB |
testcase_62 | AC | 901 ms
220,324 KB |
ソースコード
#MMA Contest 015 - K Make a Sequence #リジャッジでTLEになっていたので(は?) リベンジ #static Li Chao Tree class Li_Chao_Tree: def __init__(self, X_list): #X_list: 線分追加・最小値計算で使用する、すべてのx座標 #_X[i] = x, _D[x] = i x座標とLi Chao Tree上のノードを対応 #_L[i] = (a, b): 区間の最大値候補たり得る線分 y = ax + b #_S[i] = (Lt, mid, Rt): ノードの区間(index表記) [X[Lt], X[Rt]]の閉区間が対象 self._inf = inf = 4 * 10 ** 18 X_list = sorted(set(X_list + [inf])) self._N = N = len(X_list) self._logN = logN = (N - 1).bit_length() self._size = size = 1 << logN self._X = X = X_list + [inf] * (size - N) self._D = D = {x: i for i, x in enumerate(X_list)} self._L = L = [None] * 2 * size self._S = S = [None] * size + [(i, i, i) for i in range(size)] for i in range(size - 1, 0, -1): S[i] = (S[i << 1][0], S[i << 1 | 1][0], S[i << 1 | 1][2]) def _f(self, line, x): return line[0] * x + line[1] def _add_line(self, line, i): #ノードi(と、その子)に線分を追加 Q = [(i, line)] while Q: i, line = Q.pop() if self._L[i] == None: self._L[i] = line continue Lt, mid, Rt = self._S[i] xL, xM, xR = self._X[Lt], self._X[mid], self._X[Rt] hL = self._f(line, xL) < self._f(self._L[i], xL) hM = self._f(line, xM) < self._f(self._L[i], xM) hR = self._f(line, xR) < self._f(self._L[i], xR) if hL == hR == True: self._L[i] = line continue if hL == hR == False: continue if hM == True: self._L[i], line = line, self._L[i] if hL != hM: Q.append((i << 1, line)) else: Q.append((i << 1 | 1, line)) def add_line(self, line, x_Lt = None, x_Rt = None): #半開区間[x_Lt, x_Rt)に線分追加 if x_Lt == x_Rt == None: self._add_line(line, 1) return Lt = self._D[x_Lt] if x_Lt != None else 0 Rt = self._D[x_Rt] if x_Rt != None else self._D[self._inf] Lt, Rt = Lt + self._size, Rt + self._size while Lt < Rt: if Lt & 1: self._add_line(line, Lt) Lt += 1 if Rt & 1: Rt -= 1 self._add_line(line, Rt) Lt >>= 1 Rt >>= 1 def fold(self, x): #座標xの最小値を計算 i = self._D[x] + self._size ans = self._inf while i > 0: if self._L[i]: ans = min(ans, self._f(self._L[i], x)) i >>= 1 return ans #Z-algorithm TとS[i:]のLCP判定は、T+'$'+S のようにSに出ない文字を挟んで実行するとよい #Reference: https://tjkendev.github.io/procon-library/python/string/z-algorithm.html def Z_algorithm(S): #SとS[i:]の最長共通接頭辞を求める N=len(S); A=[0]*N; i,j=1,0; A[0]=L=N while i<L: while i+j<L and S[j]==S[i+j]: j+=1 if not j: i+=1; continue A[i]=j; k=1 while L-i>k<j-A[k]: A[i+k]=A[k]; k+=1 i+=k; j-=k return A #入力受取 N, M = map(int, input().split()) A = list(map(int, input().split())) B = list(map(int, input().split())) C = list(map(int, input().split())) #Bの(Aとの)最長共通接頭辞を計算 same = Z_algorithm(A + [0] + B)[N + 1:] #DP[i]: 列Sを[0: i)まで(つまり、i文字目の直前まで)一致させるための最小コスト とする #これはLi Chao Treeの線分追加で計算が可能 #k = same[i]として、[i: i + k)に y = C[i] * x + (DP[i] - C[i] * i) の線分を追加する LCT = Li_Chao_Tree([i for i in range(M + 2)]) LCT.add_line((0, 0), 0, 1) #初期化 for i in range(M): b = LCT.fold(i) k = same[i] if b > 10 ** 18 or k == 0: continue LCT.add_line((C[i], b - C[i] * i), i + 1, min(M, i + k) + 1) #答えを出力 ans = LCT.fold(M) print(ans if ans < 10 ** 18 else -1)