canuc80k1707·8/50

Dãy Công Tắc

Nộp bài trên LQDOJ

Bài 17 · Segment Tree

Có bóng đèn được đánh số từ đến ; ban đầu tất cả đều tắt. Bạn cần xử lý thao tác:

  • : đổi trạng thái của mọi đèn từ đến ; đèn tắt thành bật và đèn bật thành tắt;
  • : đếm số đèn đang bật trong đoạn từ đến .

Các đoạn đều bao gồm hai đầu và thao tác được thực hiện theo thứ tự.

Input

  • Dòng đầu chứa hai số nguyên và .
  • Mỗi dòng trong dòng tiếp theo chứa ba số , trong đó là hoặc theo mô tả trên.

Output

  • Với mỗi thao tác loại , in ra một dòng chứa số đèn đang bật trong đoạn hỏi.

Constraints

  • .
  • .
  • .

Scoring

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

Example

Test 1

Input

6 7
1 1 6
0 2 5
1 1 3
0 3 6
1 2 6
0 1 6
1 1 6

Output

0
2
2
4

Giải thích: Sau lần lật đầu, các đèn sáng; lần lật tiếp theo để lại đèn và sáng. Lật toàn bộ sau đó làm đúng đèn sáng.

Lời giải tóm tắt
  • Phân tích: Mỗi node lưu số đèn đang bật trong đoạn. Nếu lật toàn bộ đoạn dài len, số đèn bật đổi từ on thành len-on. Một cờ lazy bit cho biết đoạn còn một phép lật chưa đẩy xuống; vì hai lần lật triệt tiêu, các cờ được hợp thành bằng XOR.
  • Thuật toán: Với update phủ trọn node: thay on = len-on và đảo cờ lazy.
  • Thuật toán: Với update/query giao một phần: đẩy cờ xuống hai con, xử lý tiếp rồi cộng số đèn bật của hai con.
  • Thuật toán: Query ngoài đoạn trả 0, query phủ trọn trả ngay on.
  • Chứng minh tính đúng đắn: Công thức len-on đúng vì mỗi đèn bật trở thành tắt và ngược lại. Cờ XOR biểu diễn đúng parity số lần lật chưa đẩy; push chuyển đúng cùng hiệu ứng cho hai con mà không đổi trạng thái quan sát được của đoạn. Sau khi xử lý một phần, tổng số đèn bật của cha bằng tổng hai con, nên bất biến được giữ sau mọi update.
  • Chứng minh tính đúng đắn: Query ghép các đoạn con rời nhau phủ đúng đoạn cần hỏi, và mỗi node đã phản ánh đầy đủ các lazy tag của nó. Vì thế tổng trả về chính xác.
  • Độ phức tạp: Mỗi thao tác O(log N), bộ nhớ O(N).