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
", sum);
            }
            else break;
        }
    }
}

  

原文地址:https://www.cnblogs.com/tenlee/p/4552880.html