canuc80k6507·8/50

Đảo đoạn và tính tổng

Nộp bài trên LQDOJ

Bài 65 · Balanced Binary Search Tree

Duy trì một mảng số qua hai loại thao tác: đảo một đoạn và tính tổng các phần tử trong đoạn đó.

Mỗi truy vấn có dạng , với chỉ số đánh từ :

  • : đảo thứ tự đoạn ;
  • : in tổng các phần tử trong đoạn .

Input

  • Dòng đầu chứa . Dòng thứ hai chứa phần tử ban đầu. Mỗi dòng trong số dòng tiếp theo chứa .

Output

  • Với mỗi truy vấn loại , in tổng đoạn được hỏi.

Constraints

  • .
  • ; tổng đoạn có thể cần số nguyên -bit.

Scoring

  • Subtask small: điểm, gồm test nhỏ.
  • Subtask full: điểm, gồm test không có giới hạn bổ sung ngoài phần Constraints.
  • Mỗi test có giá trị điểm.

Example

Test 1

Input

6 5
2 1 4 0 3 5
2 1 3
1 2 5
2 2 4
1 1 6
2 4 6

Output

7
7
5

Giải thích: Tổng ba phần tử đầu ban đầu là ; sau khi đảo , dãy thành nên tổng cũng là . Đảo toàn dãy tạo , và tổng bằng .

Lời giải tóm tắt
  • Ý tưởng: Mỗi nút lưu tổng cây con. Với mọi truy vấn, split thành L, M=[a,b], R. Nếu loại 1, bật rev trên M. Nếu loại 2, đáp án là M->sum. Sau đó luôn merge ba đoạn về lại. Reverse không thay đổi tổng nên không cần sửa sum khi bật cờ; chỉ cần đổi hai con và truyền cờ đúng lúc.
  • Chứng minh đúng: pull duy trì tổng bằng tổng trái + giá trị nút + tổng phải, nên aggregate đúng bằng quy nạp theo cây. Split cô lập chính xác các chỉ số cần hỏi; vì vậy tổng của M là tổng đoạn. Phép đảo chỉ hoán vị phần tử trong M, không đổi tổng và cờ rev bảo đảm thứ tự logic đúng. Merge bảo toàn thứ tự nối đoạn, nên bất biến mảng được khôi phục sau truy vấn.
  • Độ phức tạp: Kỳ vọng O(log n) mỗi thao tác; O(n) bộ nhớ.