单点修改,区间查询

#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;
}

模板题:https://www.luogu.com.cn/problem/P3368

posted on 2022-01-13 12:18  Hamine  阅读(78)  评论(0编辑  收藏  举报