canuc80k6602·3/15

Phần Dư Trên Dãy

Nộp bài trên LQDOJ

Bài 66 · Segment Tree Beats

Cho dãy số nguyên không âm . Bạn cần thực hiện ba loại thao tác:

  • : tính tổng các phần tử trên đoạn đóng .
  • : với mọi trong , gán .
  • : gán riêng phần tử .

Input

  • Dòng đầu chứa và .
  • Dòng thứ hai chứa phần tử ban đầu.
  • dòng tiếp theo mô tả các thao tác theo đúng một trong ba dạng trên.

Output

  • Với mỗi thao tác loại , in tổng cần tìm trên một dòng.

Constraints

  • .
  • đối với phép gán; đối với phép modulo.
  • Các chỉ số và đoạn đều hợp lệ; tổng cần dùng số nguyên bit.

Scoring

  • Subtask ( số điểm): và mọi giá trị không vượt .
  • Subtask ( số điểm): Không có giới hạn bổ sung.

Example

Test 1

Input

4 6
10 7 5 12
1 1 4
2 1 3 6
1 1 4
3 2 20
2 2 4 7
1 2 4

Output

34
22
16

Giải thích: Sau phép modulo đầu, ba phần tử đầu trở thành , nên tổng là . Sau khi gán vị trí bằng rồi lấy modulo trên đoạn cuối, đoạn có tổng .

Lời giải tóm tắt
  • Mô hình: Hỗ trợ truy vấn tổng, lấy phần dư theo một số trên đoạn và gán một phần tử.
  • Thuật toán: Cây lưu tổng và cực đại. Nếu cực đại nhỏ hơn mô-đun thì cả đoạn không đổi; mỗi lần một giá trị thật sự đổi bởi modulo, nó giảm xuống dưới một nửa.
  • Thuật toán: Các truy vấn đọc kết quả từ các thống kê đã được duy trì. Mọi thao tác lazy đều được đẩy xuống trước khi tách nút, rồi nút cha được ghép lại từ hai con.
  • Tính đúng đắn: Ta chứng minh bằng quy nạp theo cây. Ở lá, giá trị lưu chính là giá trị hiện tại của phần tử. Ở một nút trong, điều kiện áp dụng nhanh chỉ được dùng khi thống kê của nút chứng minh rằng mọi phần tử chịu cùng một biến đổi; vì vậy cập nhật các trường tổng hợp là chính xác. Nếu điều kiện đó không đúng, thuật toán đẩy tag, xử lý hai con và ghép lại, nên giả thiết quy nạp cho kết quả đúng. Các nhánh bị bỏ qua đều nằm ngoài đoạn hoặc đã được chứng minh là bất biến. Do đó mọi cập nhật và truy vấn đều đúng theo contract.
  • Độ phức tạp: Amortized O((n+m) log n log V); bộ nhớ O(n).