Hướng dẫn giải của Simple range sum
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Tác giả:
Ý tưởng làm bài
- Dùng mảng cộng dồn là chưa đủ trong bài này
- Bài này ta cần dùng một vài cấu trúc dữ liệu như cây phân đoạn, bảng thưa thớt, cây chỉ số nhị phân...
- Hãy tự tìm hiểu và hoàn thành bài tập này
Cây chỉ số nhị phân \~ Binary Indexed Tree \~ Fenwick
- Code dưới này chỉ cập nhật được giá trị một số, và lấy tổng của một đoạn thôi.
- Còn muốn cập nhật được giá trị của một đoạn, và lấy tổng của một đoạn thì phải sửa lại code để tối ưu hơn. (Cái này tự tìm hiểu nha). (ngoài bài cập nhật giá trị một đoạn tăng lên 1 giá trị x nào đó, còn có nhiều bài khác như cập nhật một đoạn và những phần tử trong đoạn đó tăng lần lượt từ 1 tới hết đoạn đó (chứ không phải cùng một giá trị x như trên),...)
#include <bits/stdc++.h>
using namespace std;
#define int long long
main() {
ios_base::sync_with_stdio (0); cin.tie (0);
int n; cin >> n;
vector <int> a(n);
for(int i=0; i<n; ++i){
cin >> a[i];
}
vector <int> sum(n+1);
function <void(int, int)>
add = [&](int id, int x){
for( ; id<=n; ){
sum[id]+=x;
id+=id&-id;
}
};
function <int(int)>
getSum = [&](int id){
int res=0;
for( ; id; ){
res+=sum[id];
id-=id&-id;
}
return res;
};
for(int i=0; i<n; ++i){
add(i+1, a[i]);
}
int q; cin >> q;
for(int i=0; i<q; ++i){
int type; cin >> type;
if(type==1){
int left; cin >> left;
int right; cin >> right;
int ans=getSum(right)-getSum(left-1);
cout <<ans <<endl;
}
else if(type==0){
int id; cin >> id;
int x; cin >> x;
add(id, x);
}
}
return 0;
}
Bình luận