树状数组 基本 c++
1.好处:时间复杂度为nlogn,效率更优。
//学就对了//
长这样 (c数组就是树状数组)

2.lowbit(灵魂)
含义:取出 x 的二进制里最右边的1后面所有的0
x=6 (110) ⇒ lowbit(6)=2——————//2的1次方
x=8 (1000) ⇒ lowbit(8)=8——————//2的3次方
x=4 (100) ⇒ lowbit(4)=4————————//2的2次方
代码:
int lowbit(int x)
{
return x & -x;
}
3.两个基础操作:
① add(x,val) 单点加val
② query(x) a[n]~a[m]的前缀和
①、不断往父节点更新,x += lowbit(x) 直到 x>n停止。
void add(int x, int val)
{
for (;x<=n; x += lowbit(x))
{
tr[x] += val;
}
}
②:向下累加,不断去掉最低位1,<x-= lowbit(x)> 直到x=n停止。

//图中啊a[1]到a[6]直接用tr[4]+tr[6]就行。
代码实现
int query(int n,int m)
{
int res=0;
for (;x>=n-1; x -= lowbit(x))
{
res += tr[x];
}
return res;
}
完整代码
#include<bits/stdc++.h>
using namespace std;
int n;
int tr[MAXN];
int lowbit(int x)
{
return x & -x;
}
void add(int x, int val)
{
for (; x <= n; x += lowbit(x))
tr[x] += val;
}
int query(int x)
{
int res = 0;
for (; x > 0; x -= lowbit(x))
res += tr[x];
return res;
}
// 查询区间 [l, r] 的和
int range_query(int l, int r)
{
return query(r) - query(l - 1);
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int v;
cin >> v;
add(i, v);
}
while(m--)
{
int op;
cin >> op;
if(op == 1) // 单点加
{
int pos, val;
cin >> pos >> val;
add(pos, val);
}
else
{
int l, r;
cin >> l >> r;
cout << range_query(l, r) << '\n';
}
}
return 0;
}
结束qwq

浙公网安备 33010602011771号