树状数组小结
第一次接触树状数组,a了2道pku上练习树状数组的基础题。故此做个总结。
树状数组理论来源:武钢三中 吴豪 树状数组
一维树状数组相关函数:
//计算最小幂2^i
int Lowbit(int i)
{
return i & (i ^ (i - 1));
}
//计算树状数组的前n项和
int Sum(int end)
{
int sum = 0;
while (end > 0)
{
sum += Tree[end];
end -= Lowbit(end);
}
return sum;
}
//更新树状数组
void Update_Tree(int x)
{
while (x < M)
{
Tree[x]++;
x += Lowbit(x);
}
}
相关练习:
http://acm.pku.edu.cn/JudgeOnline/problem?id=2352
AC代码:
#include <stdio.h>
#define M 32005
int n, Tree[M], ans[M];
//计算最小幂2^i
int Lowbit(int i)
{
return i & (i ^ (i - 1));
}
//计算树状数组的前n项和
int Sum(int end)
{
int sum = 0;
while (end > 0)
{
sum += Tree[end];
end -= Lowbit(end);
}
return sum;
}
void Update_Tree(int x)
{
while (x < M)
{
Tree[x]++;
x += Lowbit(x);
}
}
int main()
{
//freopen("1.txt", "r", stdin);
int i, x, y;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d%d", &x, &y);
ans[Sum(x + 1)]++; //别忘了数组下标从零开始
Update_Tree(x + 1);
}
for (i = 0; i < n; i++)
{
printf("%d/n", ans[i]);
}
return 0;
}
同样可以应用在二维的数组上:
int Lowbit(int x)
{
return x & -x;
}
//
void update(int i, int j, int num)
{
while (i > 0)
{
int temp = j;
while (temp > 0)
{
Tree[i][temp] += num;
temp -= Lowbit(temp);
}
i -= Lowbit(i);
}
}
int sum(int x, int y)
{
int temp = 0;
for (int i = x; i <= N; i += Lowbit(i))
{
for (int j = y; j <= N; j += Lowbit(j))
{
temp += Tree[i][j];
}
}
return temp;
}
相关练习:
http://acm.pku.edu.cn/JudgeOnline/problem?id=2155
#include <stdio.h>
#include <string.h>
#define M 1005
int N, T;
int Tree[M][M];
int Lowbit(int x)
{
return x & -x;
}
void update(int i, int j, int num)
{
while (i > 0)
{
int temp = j;
while (temp > 0)
{
Tree[i][temp] += num;
temp -= Lowbit(temp);
}
i -= Lowbit(i);
}
}
int sum(int x, int y)
{
int temp = 0;
for (int i = x; i <= N; i += Lowbit(i))
{
for (int j = y; j <= N; j += Lowbit(j))
{
temp += Tree[i][j];
}
}
return temp;
}
int main()
{
//freopen("1.txt", "r", stdin);
int i, test;
int left1, right1, left2, right2;
int x, y;
char c[2];
scanf("%d", &test);
while (test--)
{
scanf("%d%d", &N, &T);
memset(Tree, 0, sizeof(Tree));
for (i = 0; i < T; i++)
{
scanf("%s", c);
if (c[0] == 'C')
{
scanf("%d%d%d%d", &left1, &right1, &left2, &right2);
update(left2, right2, 1);
update(left1 - 1, right2, -1);
update(left2, right1 - 1, -1);
update(left1 - 1, right1 - 1, 1);
}
else if (c[0] == 'Q')
{
scanf("%d%d", &x, &y);
printf("%d/n", sum(x, y) % 2);
}
}
printf("/n");
}
return 0;
}