This documentation is automatically generated by online-judge-tools/verification-helper
import cp_library.__header__
from cp_library.alg.dp.monotone_minima_fn import monotone_minima
import cp_library.math.__header__
import cp_library.math.conv.__header__
def minplus_conv_arb_cnvx(arb: list[int], cnvx: list[int]) -> list[int]:
N, M = len(cnvx), len(arb)
def cmp(i, j, k):
return i >= k and (i-j >= N or (cnvx[i-j] + arb[j] >= cnvx[i-k] + arb[k]))
cols = monotone_minima(N+M-1, M, cmp)
return [arb[j] + cnvx[i-j] for i, j in enumerate(cols)]
def minplus_conv_cnvx(A: list[int], B: list[int]) -> list[int]:
if not (N := len(A)) | (M := len(B)): return []
C = [0] * (K:=N+M-1)
C[0], I, J = A[i := 0] + B[j := 0], N-1, M-1
for k in range(1, K):
if j == J or (i != I and A[i+1] + B[j] < A[i] + B[j+1]): i += 1
else: j += 1
C[k] = A[i] + B[j]
return C
def minplus_iconv(A: list[int], B: list[int]):
N, M = len(A), len(B)
for i in range(N-1,-1,-1):
A[i] = min(B[j] + A[i-j] for j in range(min(M,i+1)))
'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
https://kobejean.github.io/cp-library
'''
from typing import Callable
def monotone_minima(N: int, M: int, func: Callable[[int,int,int],bool]):
'''
Finds row minima in a totally monotone N×M matrix using the SMAWK algorithm.
The matrix is defined implicitly through the comparison function.
A matrix is totally monotone if the minimum in row i occurs at column j,
then the minimum in row i+1 must occur at column j' where j ≤ j'.
Time: O(N log M), Space: O(N)
Args:
N: Number of rows
M: Number of columns
func(i,j,k): Returns True if element (i,j) < element (i,k)
Returns:
List of column indices containing the minimum value for each row
Example:
# Find minima where each element is (i-j)²
min_indices = monotone_minima(5, 5, lambda i,j,k: (i-j)**2 < (i-k)**2)
'''
min_j, st = [0] * N, elist(N)
st.append((0, N, 0, M))
while st:
li, ri, lj, rj = st.pop()
if li == ri: continue
mi, mj = li + ri >> 1, lj
for j in range(lj + 1, rj):
if func(mi, mj, j): mj = j
min_j[mi] = mj
st.append((li, mi, lj, mj+1))
st.append((mi+1, ri, mj, rj))
return min_j
def elist(est_len: int) -> list: ...
try:
from __pypy__ import newlist_hint
except:
def newlist_hint(hint):
return []
elist = newlist_hint
'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
x₀ ────────●─●────────●───●────────●───────●────────► X₀
╳ ╲ ╱ ╲ ╱
x₄ ────────●─●────────●─╳─●────────●─╲───╱─●────────► X₁
╳ ╳ ╲ ╲ ╱ ╱
x₂ ────────●─●────────●─╳─●────────●─╲─╳─╱─●────────► X₂
╳ ╱ ╲ ╲ ╳ ╳ ╱
x₆ ────────●─●────────●───●────────●─╳─╳─╳─●────────► X₃
╳ ╳ ╳ ╳
x₁ ────────●─●────────●───●────────●─╳─╳─╳─●────────► X₄
╳ ╲ ╱ ╱ ╳ ╳ ╲
x₅ ────────●─●────────●─╳─●────────●─╱─╳─╲─●────────► X₅
╳ ╳ ╱ ╱ ╲ ╲
x₃ ────────●─●────────●─╳─●────────●─╱───╲─●────────► X₆
╳ ╱ ╲ ╱ ╲
x₇ ────────●─●────────●───●────────●───────●────────► X₇
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
Math - Convolution
'''
def minplus_conv_arb_cnvx(arb: list[int], cnvx: list[int]) -> list[int]:
N, M = len(cnvx), len(arb)
def cmp(i, j, k):
return i >= k and (i-j >= N or (cnvx[i-j] + arb[j] >= cnvx[i-k] + arb[k]))
cols = monotone_minima(N+M-1, M, cmp)
return [arb[j] + cnvx[i-j] for i, j in enumerate(cols)]
def minplus_conv_cnvx(A: list[int], B: list[int]) -> list[int]:
if not (N := len(A)) | (M := len(B)): return []
C = [0] * (K:=N+M-1)
C[0], I, J = A[i := 0] + B[j := 0], N-1, M-1
for k in range(1, K):
if j == J or (i != I and A[i+1] + B[j] < A[i] + B[j+1]): i += 1
else: j += 1
C[k] = A[i] + B[j]
return C
def minplus_iconv(A: list[int], B: list[int]):
N, M = len(A), len(B)
for i in range(N-1,-1,-1):
A[i] = min(B[j] + A[i-j] for j in range(min(M,i+1)))