acwing算法提高之数据结构--树状数组

1 介绍

本专题用来记录树状数组相关题目。

lowbit(x)操作,求数 x二进制表示中最低位的1的值,

int lowbit(int x) {
   
	return x & -x;
}

树状数组:用来快速计算动态前缀和的数据结构。

c[x]的表示原数组以第x个数结尾,且区间长度为lowbit(x)的区间的和,即c[x - lowbit(x) + 1] ~ c[x]

在这里插入图片描述

树状数组支持两种操作:

  1. 单点修改,比如a[i] += x
  2. 区间查询,比如求a[l~r]的和

见上图,修改a[5]的值,则需要递次修改c[5], c[6], c[8]的值。那么修改操作的代码如下,

//a[x] += k
void add(int x, int k) {
   
  while (x <= n) {
     // 不能越界。n就是最大值,总共n个数,编号分别为1,2,3...,n
    c[x] = c[x] + k;
    x = x + lowbit(x);
  }
}

//或可以写成
void add(int x, int k) {
   
	for (int i = x; i <= n; i += lowbit(i)) {
   
		c[i] += k;
	}
}

见上图,查询前缀和a[1~5],则需要递次遍历c[5], c[4], c[0],将它们的值累加就是前缀和。那么求前缀和的代码如下,

int getsum(int x) {
     // a[1]..a[x]的和
  int ans = 0;
  while (x >= 1) {
   
    ans = ans + c[x];
    x = x - lowbit(x);
  }
  return ans;
}

//或可以写成
int getsum(int x) {
   
	int ans = 0;
	for (int i = x; i >= 1; i -= lowbit(i)) {
   
		ans += c[i];
	}
	return ans;
}

2 训练

题目1241楼兰图腾

C++代码如下,

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 200010;

int n;
int a[N]; //a[x] = 2表示数x出现了2次
int tr[N];
int Greater[N], lower[N];

int lowbit(int x) {
   
    return x & -x;
}

void add(int x, int c) {
   
    for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}

int sum(int x) {
   
    int res = 0;
    for (int i 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YMWM_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值