canuc80k4110·11/15

Cặp Trùng Trong Đoạn

Nộp bài trên LQDOJ

Bài 41 · Divide and Conquer DP and Knuth

Cho dãy . Với một đoạn , chi phí của đoạn là số cặp chỉ số thỏa và . Mỗi cặp chỉ được đếm một lần.

Hãy chia dãy thành đúng đoạn liên tiếp không rỗng sao cho tổng chi phí của các đoạn nhỏ nhất.

Input

  • Dòng đầu gồm .
  • Dòng thứ hai gồm .

Output

  • In tổng chi phí nhỏ nhất.

Constraints

  • .
  • .
  • .
  • Kết quả dùng số nguyên bit.

Scoring

  • Subtask (): .
  • Subtask (): không có ràng buộc thêm.

Example

Test 1

Input

7 3
1 1 3 3 3 2 1

Output

1

Giải thích: Chia dãy thành ba đoạn mang các giá trị [1], và . Chỉ đoạn giữa có một cặp phần tử bằng nhau, là cặp , nên tổng chi phí bằng .

Lời giải tóm tắt
  • Ý tưởng: Nếu một giá trị xuất hiện f lần trong đoạn, nó đóng góp f(f-1)/2. Duy trì cửa sổ [L,R], bảng tần suất và cost: khi thêm giá trị x, cộng số lần x hiện có rồi tăng tần suất; khi xóa, giảm tần suất trước rồi trừ tần suất mới.
  • Ý tưởng: Đặt dp[g][r] là chi phí nhỏ nhất cho r phần tử đầu với g đoạn. Đoạn cuối [p+1,r] cho recurrence min(dp[g-1][p]+cost(p+1,r)). Hàm số cặp bằng nhau là Monge (xét riêng từng giá trị), nên điểm chia tối ưu không giảm theo r; tính mỗi hàng bằng Divide and Conquer optimization và lấy cost qua cửa sổ động.
  • Ý tưởng: Các cập nhật thêm/xóa bảo toàn đúng số cặp; recurrence xét mọi đoạn cuối; tính Monge bảo đảm D&C không bỏ nghiệm. Độ phức tạp O(KN log N), bộ nhớ O(N).