现在的位置: 首页 > 综合 > 正文

二维树状数组

2012年08月18日 ⁄ 综合 ⁄ 共 2344字 ⁄ 字号 评论关闭

思路不难,比一维的只多了层循环,代码也很短。详见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;
}

抱歉!评论已关闭.