您的位置:首页 > 其它

二维树状数组

2011-07-20 12:56 267 查看
思路不难,比一维的只多了层循环,代码也很短。详见NOCOW的讲解

POJ 1656

/*
题意:一块方格板,要求把一个正方形区域涂黑/涂白/统计黑的数目

算法:二维树状数组

注意:update的时候下标从x和y开始不是习惯的1啊!!!编译前就发现主程序中的错误改了,没想到update函数里也写错了,半天看不出来啊!!!

2011-07-18 14:11
*/

#include <stdio.h>

#define MAXN 200

int flag[MAXN][MAXN];
int c[MAXN][MAXN];

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

void update(int x, int y, int color)
{
if (color == flag[x][y])
return ;
flag[x][y] = color;
int i, j;
for (i = x; i <= MAXN; i += lowbit(i))
for (j = y; j <= MAXN; j+= lowbit(j))
c[i][j] += color;
}

int getsum(int x, int y)
{
int sum = 0, i, j;
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 t, k, i, j, x, y, l;
char s[10];

scanf("%d", &t);
memset(c, 0, sizeof(c));
memset(flag, -1, sizeof(flag));
for (k = 1; k <= t; k++)
{
scanf("%s%d%d%d", &s, &x, &y, &l);
if (s[0] =='B')
{
for (i = x; i <= x+l-1; i++)
for (j = y; j <= y+l-1; j++)
update(i, j, 1);
}
else if (s[0] == 'W')
{
for (i = x; i <= x+l-1; i++)
for (j = y; j <= y+l-1; j++)
update(i, j ,-1);
}
else
printf("%d\n", getsum(x+l-1, y+l-1) - getsum(x+l-1,y-1) - getsum(x-1, y+l-1) + getsum(x-1, y-1));
}
return 0;
}


POJ 1195

/*
改点、求一块矩形区域的和,二维树状数组解决。因为当值小于0的时候要变为0,所以保留了原数组并多加了判断

不能再把j打成i了!!!

开始的时候打成和上次做的改区域一样了,WA了好久。

2011年7月20日12:53:26
*/

#include <stdio.h>

#define MAXN 1200

int c[MAXN][MAXN];
int a[MAXN][MAXN];
int n;

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

void add(int x, int y, int num)
{
int i, j;
//printf("%d %d %d %d\n", n, x, y, num);
for (i = x; i <= n; i += lowbit(i))
for (j = y; j <= n; j += lowbit(j))
c[i][j] += num;

}

int ask(int x, int y)
{
int i, j, ans = 0;

for (i = x; i >= 1; i -= lowbit(i))
for (j = y; j >= 1; j -= lowbit(j))
ans += c[i][j];
return ans;
}

int query(int x1, int y1, int x2, int y2)
{
return ask(x2, y2) - ask(x1 - 1, y2) - ask(x2, y1 - 1) + ask(x1 - 1, y1 -1);
}

int main()
{
int cmd, s, x, y, x1, y1, x2, y2, k;

scanf("%d%d", &k, &n);
while (scanf("%d", &cmd) && (cmd != 3))
{
if (cmd == 1)
{
scanf("%d%d%d", &x, &y, &k);
if (k < 0 && a[x+1][y+1] + k < 0)
k = 0 - a[x+1][y+1];
a[x+1][y+1] += k;
add(x + 1, y + 1, k);
}
else if (cmd == 2)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
//printf("output\n");
printf("%d\n", query(x1 + 1, y1 + 1, x2 + 1, y2 + 1));
}
}
return 0;
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: