1、POJ 1195 Mobile phones
http://acm.pku.edu.cn/JudgeOnline/problem?id=1195
二维的树状数组,要参照一维画图理解。
#include <stdio.h>
#include <string.h>
const int MAX = 1030;
int size;
int c[MAX][MAX];
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int y, int t)
{
int i, j;
for (i=x; i<=size; i+=lowbit(i))
{
for (j=y; j<=size; j+=lowbit(j))
{
c[i][j] += t;
}
}
}
int getsum(int x, int y)
{
int i, j, sum = 0;
for (i=x; i>0; i-=lowbit(i))
{
for (j=y; j>0; j-=lowbit(j))
{
sum += c[i][j];
}
}
return sum;
}
int main()
{
int ins, x, y, A, l, b, r, t;
memset(c, 0, sizeof(c));
while (scanf("%d", &ins) == 1)
{
if (ins == 0)
{
scanf("%d", &size);
}
if (ins == 1)
{
scanf("%d%d%d", &x, &y, &A);
x++;
y++;
update(x, y, A);
}
if (ins == 2)
{
scanf("%d%d%d%d", &l, &b, &r, &t);
l++;
b++;
r++;
t++;
printf("%d\n", getsum(r, t) - getsum(r, b-1) - getsum(l-1, t) + getsum(l-1, b-1));
}
if (ins== 3)
{
break;
}
}
return 0;
}
2、POJ 2029 Get Many Persimmon Trees
http://acm.pku.edu.cn/JudgeOnline/problem?id=2029
需要枚举起点,然后用二维树状数组,更新即可。
#include <stdio.h>
#include <string.h>
#define max(x,y) (x)>(y)?(x):(y)
const int MAX = 505;
int c[MAX][MAX];
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int y, int v)
{
int i, j;
for (i=x; i<MAX; i+=lowbit(i))
{
for (j=y; j<MAX; j+=lowbit(j))
{
c[i][j] += v;
}
}
}
int getsum(int x, int y)
{
int i, j, sum = 0;
for (i=x; i>0; i-=lowbit(i))
{
for (j=y; j>0; j-=lowbit(j))
{
sum += c[i][j];
}
}
return sum;
}
int main()
{
int n, w, h, x, y, s, t, i, j, ans;
while (scanf("%d", &n) == 1, n)
{
ans = 0;
scanf("%d%d", &w, &h);
memset(c, 0, sizeof(c));
for (i=0; i<n; i++)
{
scanf("%d%d", &x, &y);
update(x, y, 1);
}
scanf("%d%d", &s, &t);
for (i=1; i<=w-s+1; i++)
{
for (j=1; j<=h-t+1; j++)
{
ans = max(ans, getsum(i+s-1,j+t-1)+getsum(i-1, j-1)-getsum(i+s-1, j-1)-getsum(i-1, j+t-1));
}
}
printf("%d\n", ans);
}
return ans;
}
3、SPOJ 1029 Matrix Summation
https://www.spoj.pl/problems/MATSUM/
依旧是二维
#include <stdio.h>
#include <string.h>
const int MAX = 1024 + 10;
char ins[5];
int n, a[MAX][MAX], c[MAX][MAX], x, y;
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int y, int v)
{
int i, j;
for (i=x; i<=n; i+=lowbit(i))
{
for (j=y; j<=n; j+=lowbit(j))
{
c[i][j]+=v;
}
}
}
int getsum(int x, int y)
{
int i, j, sum = 0;
for (i=x; i>0; i-=lowbit(i))
{
for (j=y; j>0; j-=lowbit(j))
{
sum += c[i][j];
}
}
return sum;
}
int main()
{
int Case, v;
while(scanf("%d", &Case) == 1)
{
while (Case--)
{
scanf("%d", &n);
memset(a, 0, sizeof(a));
memset(c, 0, sizeof(c));
while (scanf("%s", ins)==1&&strcmp(ins, "END"))
{
if (strcmp(ins, "SET") == 0)
{
scanf("%d%d%d", &x, &y, &v);
x++;
y++;
update(x, y, v-a[x][y]);
a[x][y] = v;
}
if (strcmp(ins, "SUM") == 0)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1++;
y1++;
x2++;
y2++;
printf("%d\n", getsum(x2,y2) + getsum(x1-1, y1-1) - getsum(x2, y1-1)-getsum(x1-1, y2));
}
}
}
}
return 0;
}