单点修改,区间查询
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
struct Fenwick{
int n;
vector<int> a;
Fenwick(int n) : n(n), a(n + 1) {}
LL sum(int x){
LL res = 0;
for (; x; x -= x & -x){
res += a[x];
}
return res;
}
void add(int x, int k){
for (; x <= n; x += x & -x){
a[x] += k;
}
}
LL query(int x, int y){
return sum(y) - sum(x - 1);
}
};
int main(){
ios::sync_with_stdio(false);cin.tie(0);
int n, m;
cin >> n >> m;
Fenwick fwt(n);
for (int i = 1; i <= n; i ++ ){
int x;
cin >> x;
fwt.add(i, x);
}
while (m -- ){
int op, x, y, k;
cin >> op;
if (op == 1){
cin >> x >> k;
fwt.add(x, k);
}
else{
cin >> x >> y;
cout << fwt.query(x, y) << "\n";
}
}
return 0;
}
应用:
模板题:https://www.luogu.com.cn/problem/P3374
求解逆序对:https://www.cnblogs.com/Hamine/p/15689892.html
求解康托展开:https://www.cnblogs.com/Hamine/p/16320683.html
区间修改,单点查询(差分)
#include <bits/stdc++.h>
using namespace std;
#define LL long long
struct fwt{
LL n;
vector <LL> a;
fwt(LL n) : n(n), a(n + 1) {}
LL sum(LL x){
LL res = 0;
for (; x; x -= x & -x)
res += a[x];
return res;
}
void add(LL x, LL k){
for (; x <= n; x += x & -x)
a[x] += k;
}
LL query(LL x, LL y){
return sum(y) - sum(x - 1);
}
};
LL n, m;
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cin >> n >> m;
fwt a(n);
vector <int> b(n + 1);
for (int i = 1; i <= n; i ++ )
cin >> b[i];
while (m -- ){
LL op, x, y, k;
cin >> op;
if (op == 1){
cin >> x >> y >> k;
a.add(x, k);
a.add(y + 1, -k);
}
else{
cin >> x;
cout << b[x] + a.query(1, x) << "\n";
}
}
return 0;
}