概念
https://zhuanlan.zhihu.com/p/92920381
树状数组(Binary Indexed Tree, 又Fenwick Tree)其实并不是一棵树,只是对数组各元素进行逻辑上的划分。根据维基百科,树状数组是一种用于高效计算数列前缀和的数据结构,它可以以O(logn)的时间得到任意前缀和(两个前缀和相减即可得到区间和),并同时支持以O(logn)的时间对数组某个值进行修改,空间复杂度为O(n)。由此可见,我们可以用树状数组解此题,使sumRange
和update
的复杂度均为O(logn)。因此我们有必要来了解一下树状数组。
视频帮助理解
https://www.bilibili.com/video/BV1ce411u7qP/?spm_id_from=333.337.search-card.all.click&vd_source=41b9bfb5ef0a4175a4cb4170a475f680
题目
https://www.luogu.com.cn/problem/P3374
Code
#include <bits/stdc++.h> #include <unistd.h> using namespace std; int v[500005], bit[500005], data[500005]; int n, m; int lowBit(int j){ return j & (-j); } int sum(int i){ // 前idx个数的和, logn // 这里的i从1开始编号 int res = 0; while(i > 0){ res += bit[i]; i -= lowBit(i); } return res; } int sumRange(int i, int j) { //logn return sum(j) - sum(i-1); } void update(int i, int val) { //logn int diff = val - data[i]; data[i] = val; // bit中下标从1开始 while(i <= n){ bit[i] += diff; i += lowBit(i); } } void print(){ for(int i=1; i<=n; i++){ cout << bit[i] << ","; } cout << endl; } int main() { cin >> n >> m; for(int i=1; i<=n; i++){ cin >> v[i]; } for(int i=1; i<=n; i++){ update(i, v[i]); // cout << "-------------" << endl; // cout << "update i=" << i << " with v[i]=" << v[i] << endl; // // print(); } for(int i=0; i<m; i++){ int action, x; cin >> action >> x; if (action == 1){ // add k to x pos int k; cin >> k; update(x, k+data[x]); // cout <<"----- add k=" << k << " to x=" << x << endl; // print(); } else if (action == 2){ // query sum in the range of [x, y] int y; cin >> y; cout << sumRange(x, y) << endl; } } }
标签:return,树状,int,数组,logn,data From: https://www.cnblogs.com/lightsong/p/17546143.html