POJ 1195 Mobile phones(二维树状数组)

题目链接: 戳我

题目大意:

给你一个二维数组 a[][] , 有以下几种操作,0 S 就是把数组初始化为0

1 X Y A 就是让   a[X][y] = A;

2 L  B R T 就是求矩阵a[L][B] 和 a[R][T] 所围矩形内的和

3 退出

简单的二维树状数组, 不懂得看这篇博客,挺好的, 尤其是还解释了树状数组lowbit  戳我

代码C++比G++快了一倍:

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cctype>

#include <cmath>

#include <algorithm>

#include <vector>

#include <queue>

#include <stack>

#include <map>



using namespace std;

#define clc(a, b) memset(a, b, sizeof(a))

const int inf = 0x3f;

const int INF = 0x3f3f3f3f;

const int maxn = 1050;



int a[maxn][maxn], n;



void Init()

{

    clc(a, 0);

}



int lowbit(int x)

{

    return x & -x;

}

void Add(int x, int yy, int val)

{

    while(x <= n)

    {

        int y = yy;

        while(y <= n)

        {

            a[x][y] += val;

            y += lowbit(y);

        }

        x += lowbit(x);

    }

}



int Sum(int x, int y)

{

    int sum = 0, yy;

    while(x)

    {

        yy = y;

        while(yy)

        {

            sum += a[x][yy];

            yy -= lowbit(yy);

        }

        x -= lowbit(x);

    }

    return sum;

}

int main()

{

    int op, x, y, l, x1, y1, x2, y2, sum;

    while(~scanf("%d", &op))

    {

        scanf("%d", &n);

        if(op == 0) Init();

        while(true)

        {

            scanf("%d", &op);

            if(op == 1)

            {

                scanf("%d %d %d", &x, &y, &l);

                Add(x+1, y+1, l);

            }

            else if(op == 2)

            {

                scanf("%d %d %d %d", &x1, &y1, &x2, &y2);

                x1++; y1++; x2++; y2++;

                sum = Sum(x2, y2) - Sum(x1-1, y2) - Sum(x2, y1-1) + Sum(x1-1, y1-1);

                printf("%d\n", sum);

            }

            else break;

        }

    }

}

  

 

你可能感兴趣的:(mobile)