(模板)树状数组
单点修改 + 区间查询
神奇的代码
#define int long long
#define lowbit(x) x & -x
const int maxn = 5e5 + 5;
int fenwick[maxn];
int n = 0; // 数据个数
int query(int pos) // 查询[1, pos]区间信息
{
int res = 0;
while(pos > 0)
{
res += fenwick[pos];
pos -= lowbit(pos);
}
return res;
}
// 单点修改 + 区间查询
void modify(int pos, int x)
{
while(pos <= n)
{
fenwick[pos] += x;
pos += lowbit(pos);
}
}
int range_sum(int l, int r)
{
return query(r) - query(l - 1);
}
区间修改 + 单点查询 + 区间查询
神奇的代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define lowbit(x) x & -x
using lli = long long;
const int maxn = 5e5 + 5;
int fenwick1[maxn], fenwick2[maxn]; // fenwick1维护dif[i], fenwick2维护dif[i] * i
int nums[maxn];
int n = 0; // 数据个数
void modify(int pos, int x)
{
int val = pos * x;
while(pos <= n)
{
fenwick1[pos] += x;
fenwick2[pos] += val;
pos += lowbit(pos);
}
}
int query(int pos, int t[]) // [1, pos]的区间信息
{
int res = 0;
while(pos > 0)
{
res += t[pos];
pos -= lowbit(pos);
}
return res;
}
// 区间修改 + 区间查询
void range_modify(int l, int r, int x)
{
modify(l, x);
modify(r + 1, -x);
}
int range_query(int l, int r)
{
int pre = (r + 1) * query(r, fenwick1) - l * query(l - 1, fenwick1);
int pos = query(r, fenwick2) - query(l - 1, fenwick2);
return pre - pos;
}
// 单点查询
int single_query(int pos)
{
return query(pos, fenwick1);
}