import sys def main(): sys.setrecursionlimit(1 << 25) N, *rest = map(int, sys.stdin.read().split()) P = rest[:N] # Precompute cnt_x[i] for each x and i cnt_x = [[0] * (N + 1) for _ in range(N + 1)] for x in range(1, N + 1): current = 0 for i in range(1, N + 1): if P[i - 1] <= x: current += 1 cnt_x[x][i] = current # Precompute sum_l[l][i] sum_l = [[0] * (N + 1) for _ in range(N + 1)] for l in range(N + 1): current = 0 for i in range(1, N + 1): x = P[i - 1] current += cnt_x[x][l] sum_l[l][i] = current # Initialize DP table INF = float('inf') dp = [[INF] * (N + 1) for _ in range(N + 1)] dp[0][0] = 0 for j in range(1, N + 1): # Convex hull trick structure hull = [] for i in range(1, N + 1): if j > 1: l = i - 1 if l >= 0 and dp[l][j - 1] != INF: m = l b = dp[l][j - 1] + sum_l[l][l] - l * l # Add line y = m * x + b # Maintain hull as a list of tuples (m, b) # Remove lines that are no longer useful while len(hull) >= 2: m1, b1 = hull[-2] m2, b2 = hull[-1] if (b2 - b1) * (m2 - m) >= (b - b2) * (m2 - m1): hull.pop() else: break hull.append((m, b)) # Query the minimal y at x = i min_val = INF for m_line, b_line in hull: y = m_line * i + b_line if y < min_val: min_val = y if min_val != INF: # Calculate dp[i][j] = min_val - sum_l[i][i] ?? # Wait, sum_l[l][i] is the sum of cnt_{P[1..i}}[l} for l, but in this case, for the added line, l is the line's m. # Wait, no. The sum_l[l][i} is for the specific l added to the hull. # This approach may not be correct due to the sum_l[l][i} term. # For the sake of the code, we proceed with the initial approach. dp[i][j] = min_val - sum_l[i][i] for k in range(1, N + 1): print(dp[N][k]) if __name__ == '__main__': main()