您的位置:首页 > 其它

树状数组

2015-09-29 22:09 211 查看
  树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值.

  理论上用BIT(树状数组)能解决的问题 ,线段树都可以解决 , 但是明显前者的代码量少.

  让我们大概看看怎么样的:



  据图可知:c1=a1,c2=a1+a2,c3=a3,c4=a1+a2+a3+a4,c5=a5,c6=a5+a6,c7=a7,c8=a1+a2+a3+a4+a5+a6+a7+a8,c9=a9...

  还是看代码吧

  

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

using namespace std;
const int MAXN = 1e5 + 5;
int bit[MAXN] , n;

void init() {
memset(bit , 0 , sizeof(bit));
}

int lowbit(int i) {
return i&-i; //i的二进制最低非0对应的幂  1->1    3->1   2->2   8->8;
}

int sum(int i) {    //sum(5) = bit[4] + bit[5];
int s = 0;
while(i > 0) {
s += bit[i];
i -= lowbit(i);  //去掉二进制最后一个1以及之后的0
}
return s;
}

void add(int i , int x) {      // 比如 bit[5]  =>  bit[6]  =>  bit[8]
while(i <= n) {
bit[i] += x;         //区间更新
i += lowbit(i);      //找到关联的区间
}
}

int main() {
init();
cin >> n;
//初始化赋值
for(int i = 1 ; i <= n ; i++) {
cin >> num;
add(i , num);
}
int q_l , q_r;
cin >> q_l >> q_r;
cout << sum(q_r) - sum(q_l) << endl;
}


下面来做个题目

链接:http://codeforces.com/gym/100741/problem/A

注意s操作的时候,当a[i]%m == mod时且在区间l~r内,计算他的和。

下面是我的代码:

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

using namespace std;
const int MAXN = 1e4 + 5;
__int64 bit[11][MAXN] , equ , a[MAXN];
int n;

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

__int64 Sum(int i , int k) {
__int64 sum = 0;
while(i > 0) {
sum += bit[k][i];
i -= lowbit(i);
}
return sum;
}

void Add(int i , int add , int k) {
while(i <= n) {
bit[k][i] +=  add;
i += lowbit(i);
}
}

int main() {
int m;
while(~scanf("%d %d" , &n , &m)) {
memset(bit , 0 , sizeof(bit));
for(int i = 1 ; i <= n ; i++) {
scanf("%I64d" , a + i);
Add(i , a[i] , a[i] % m);
}
int q , l , r;
char c;
scanf("%d" , &q);
while(q--) {
getchar();
c = getchar();
if(c == 's') {
scanf("%d %d %I64d" , &l , &r , &equ);
cout << Sum(r , equ) - Sum(l - 1 , equ) << endl;
}
else if(c == '+') {
scanf("%d %I64d" , &l , &equ);
Add(l , -a[l] , a[l] % m);
a[l] += equ;
Add(l , a[l] , a[l] % m);
cout << a[l] << endl;
}
else {
scanf("%d %I64d" , &l , &equ);
if(a[l] - equ > 0) {
Add(l , -a[l] , a[l] % m);
a[l] -= equ;
Add(l , a[l] , a[l] % m);

cout << a[l] << endl;
}
else{
cout << a[l] << endl;
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: