标签:范围查询 include ons one ace syn 否则 std ble
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<ll> vll;
const int INF = 0x3f3f3f3f;
const long long LLINF = 4e18;
const double EPS = 1e-9;
const int maxn = 1e6 + 10;
#define LSOne(S) ((S) & -(S)) //不加括号会导致结果出错,具体原因见P45
int n;
int ft[maxn], ft_extra[maxn]; //ft数组用于存储一个传统的树,ft_extra数组用于区间修改+区间查询时存储的另一颗树
int f[maxn]; //f数组用于存放题目输入的数据或输入数据的差分数组
int a[maxn];
ll rsq(ll i) { //求f[1]到f[i]的和,若f为差分数组则此功能为 point_query单点查询f[i]
ll sum = 0;
for (; i; i -= LSOne(i)) sum += ft[i]; //从后往前加,每次减去一个 LSOne(i)(二进制截取最后一位1)
return sum;
}
ll pq_range(ll n) { //用于计算(n+1)f[i] - i*f[i] 的前n项和
ll sum = 0;
for (int i = n; i; i -= LSOne(i)) sum += (n + 1) * ft[i] - ft_extra[i];
return sum;
}
ll rsq_range(ll l, ll r) { //range_query 范围查询,习惯上用l作为左端点,r作为右端点, f必须为差分数组
return pq_range(r) - pq_range(l - 1);
}
void update(int i, ll v) { //单点更新
for (; i <= n; i += LSOne(i)) { //从前往后更新,所有受到影响的点都要更新一遍
ft[i] += v;
ft_extra[i] += i * v; //需要进行区间修改和区间查询的时候才需要这一步
}
}
void range_update(int l, int r, ll v) { //区间更新,[l,r]内所有数 +v
update(l, v);
update(r + 1, -v);
}
void build() { //建树,复杂度O(n)
for (int i = 1; i <= n; i++) {
ft[i] += f[i];
ft_extra[i] += i * f[i];
int x = i + LSOne(i);
if (x <= n) { //如果存在父节点,顺便把父节点也更新了
ft[x] += ft[i];
ft_extra[x] += ft_extra[i];
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
f[i] = a[i] - a[i - 1]; //将f建立为输入数据的差分数组
}
cout << "input:" << endl;
for (int i = 1; i <= n; i++) cout << f[i] << " ";
cout << endl;
build();
for (int i = 1; i <= n; i++) cout << ft[i] << " ";
cout << endl;
cout << "data of [2...4] +2" << endl;
range_update(2, 4, 2);
for (int i = 1; i <= n; i++) cout << ft[i] << " ";
cout << endl;
cout << "若f为差分数组则单点查询f(3),否则计算f[1..3]的和:" << endl;
cout << rsq(3) << endl;
cout << "Query sum of data of[1...3]:" << endl;
cout << rsq_range(1, 3) << endl;
return 0;
}
标签:范围查询 include ons one ace syn 否则 std ble
原文地址:https://www.cnblogs.com/xiezeju/p/14454748.html