canuc80k3901·2/50

Phân Phòng Tối Thiểu

Nộp bài trên LQDOJ

Bài 3.10 · Sweep Line

Có lượt sử dụng phòng, lượt chiếm trọn các ngày từ đến . Hai lượt có chung ít nhất một ngày phải dùng hai phòng khác nhau. Hãy dùng ít phòng nhất và đưa ra một cách gán phòng.

Input

  • Dòng đầu chứa số nguyên .
  • Mỗi trong dòng tiếp theo chứa hai số nguyên và của một lượt sử dụng.

Output

  • Dòng đầu in số phòng tối thiểu .
  • Dòng thứ hai in số nguyên; số thứ là phòng của lượt . Các phòng được đánh số từ đến .

Constraints

  • .
  • .
  • Hai lượt có ngày kết thúc của lượt trước bằng ngày bắt đầu của lượt sau vẫn xung đột.

Scoring

  • Subtask ( số điểm): .
  • Subtask ( số điểm): Không có giới hạn bổ sung.

Example

Test 1

Input

4
1 2
2 3
4 4
3 5

Output

2
1 2 2 1

Giải thích: Hai lượt đầu cùng sử dụng ngày nên phải ở hai phòng khác nhau. Sau đó phòng rảnh trước ngày và phòng rảnh trước ngày , vì thế cách gán trên chỉ cần hai phòng.

Lời giải tóm tắt
  • Ý tưởng: Quét theo ngày bắt đầu, dùng heap các phòng đang bận và heap các số phòng đã rảnh.
  • Ý tưởng: 1. Gắn id ban đầu rồi sắp xếp khách theo a_i tăng. 2. Trước khi gán khách hiện tại, lấy khỏi busy mọi cặp có b < a_i; các phòng đó được đưa vào freeRooms. 3. Nếu freeRooms rỗng, mở phòng mới; nếu không lấy nhãn nhỏ nhất đang rảnh. 4. Đưa (b_i,room_i) vào busy và cuối cùng trả kết quả theo id gốc.
  • Tính đúng đắn: 1. Mọi phòng được lấy khỏi busy đều có khách cũ kết thúc trước ngày khách mới đến, nên tái sử dụng là hợp lệ. 2. Nếu không có phòng rảnh tại a_i, tất cả phòng hiện có đều chứa một khoảng giao với [a_i,b_i]; vì vậy bất kỳ lịch hợp lệ nào cũng phải mở thêm phòng. 3. Thuật toán chỉ mở phòng trong trường hợp bắt buộc, nên số phòng là tối thiểu.
  • Độ phức tạp: O(n log n) thời gian, O(n) bộ nhớ.
  • Lưu ý cài đặt: CSES dùng điều kiện tái sử dụng b_old < a_new, không phải <=.
  • Lưu ý cài đặt: Quên lưu id để phục hồi thứ tự đầu vào.