您的位置:首页 > 其它

【初识——树状数组】 区间求和

2015-11-27 22:05 337 查看
说树状数组其实是一个索引表,但是是一个特殊的,树状的索引表,它利用了二进制的一些特性。

就区间求和的要求来说:

首先我们用a[]数组来存储原始数据。然后在a[]之上构造c[]数组来作为树状数组。

如图

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 50005;

int t, n;
int a
;
int c
;
char s[10];
int x, y;

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

void Add(int x, int y)
{
a[x] += y;
while(x <= n)
{
c[x] += y;
x += lowbit(x);
}
}

int Sum(int x)
{
int rt = 0;
while(x > 0)
{
rt += c[x];
x -= lowbit(x);
}
return rt;
}

int Summ(int l, int r)
{
int rt = 0;
while(r >= l)
{
if(r-lowbit(r) < l)
{
rt += a[r];
r -= 1;
}
else
{
rt += c[r];
r -= lowbit(r);
}
}
return rt;
}

void Query(int a, int b)
{
printf("%d\n", Sum(b)-Sum(a-1));
//printf("%d\n", Summ(a, b));
}

int main()
{
//freopen("test.in", "r", stdin);
scanf("%d", &t);
for(int tm = 1; tm <= t; tm++)
{
scanf("%d", &n);
memset(c, 0, sizeof(c));
memset(a, 0, sizeof(a));
int y;
for(int i = 1; i <= n; i++)
{
scanf("%d", &y);
Add(i, y);
}
printf("Case %d:\n", tm);

scanf("%s", s);
while(s[0] != 'E')
{
scanf("%d%d", &x, &y);
if(s[0] == 'A') Add(x, y);
if(s[0] == 'Q') Query(x, y);
if(s[0] == 'S') Add(x, -y);
scanf("%s", s);
}
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: