Giải thích: Ban đầu đoạn 2,…,4 có tổng 1+4+3=8. Sau hai phép gán, mảng trở thành 101935, nên tổng toàn mảng là 28 và đoạn 4,…,4 có giá trị 3.
Lời giải tóm tắt
Phân tích: Fenwick Tree thuận tiện cho phép cộng tại một vị trí, trong khi thao tác của đề là gán. Ta giữ thêm mảng giá trị hiện tại để đổi một phép gán thành một lượng chênh lệch.
Phân tích: Nếu a[k] đang bằng old và cần gán thành u, tổng của mọi đoạn chứa k phải thay đổi thêm u-old. Vì vậy chỉ cần cộng u-old tại vị trí k trong Fenwick.
Thuật toán: Khởi tạo Fenwick bằng n giá trị ban đầu và giữ chúng trong mảng a.
Thuật toán: Với thao tác 1 k u:
Thuật toán: tính delta = u-a[k];
Thuật toán: cộng delta vào vị trí k của Fenwick;
Thuật toán: gán a[k]=u.
Thuật toán: Với thao tác 2 l r, in prefix(r) - prefix(l-1).
Chứng minh: Ta chứng minh bất biến: sau mỗi thao tác, tổng tiền tố do Fenwick trả về bằng tổng tiền tố của mảng hiện tại.
Chứng minh: Bất biến đúng sau khởi tạo. Một phép gán chỉ thay đổi a[k] một lượng delta; cập nhật Fenwick cũng cộng đúng delta tại k, nên mọi tiền tố chứa k thay đổi đúng lượng đó và các tiền tố còn lại không đổi. Do đó bất biến được duy trì.
Chứng minh: Từ bất biến, prefix(r)-prefix(l-1) loại bỏ các phần tử trước l và còn lại đúng tổng a[l..r]. Vì vậy thuật toán trả lời đúng mọi truy vấn.
Độ phức tạp: Khởi tạo mất O(n log n). Mỗi thao tác mất O(log n), nên tổng thời gian là O((n+q) log n) và bộ nhớ là O(n).