poj1195 Mobile phones(二维树状数组)


http://poj.org/problem?id=1195

题意:(一大坨的题)给你4种操作,0代表输入矩阵的宽度建立矩阵,1代表对矩阵中第x行y列的数加上a,2代表对坐标点(l,b)~(r,t)矩阵内的所有点求和并输出,3代表退出。


思路:首先看教程,二维树状数组说白了就是横向为1,2,1,4,1,2,1,8这样的树状数组,纵向也为1,2,1,4,1,2,1,8这样的树状数组,那么对其的操作其实就是重复到二维上而已,要搞清楚矩阵的意义。注意输入是从0开始的,所有坐标都要加一。


#include 
#include 
#include 
#include 

using namespace std;

typedef long long ll;
const int N = 1025;

int tree[N][N], n;//从当前元素开始连续往左求lowbit(x)个数的和

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

void update(int i, int j, int val)
{
    while(i <= n)
    {
        int tmp = j;
        while(tmp <= n)
        {
            tree[i][tmp]+=val;
            tmp+=lowbit(tmp);
        }
        i+=lowbit(i);
    }
}

int sum(int i, int j)
{
    int num = 0;
    while(i > 0)//说明还有组可加
    {
        int tmp = j;
        while(tmp > 0)
        {
            num+=tree[i][tmp];
            tmp-=lowbit(tmp);
        }
        i-=lowbit(i);
    }
    return num;
}

int main()
{
  //  freopen("in.txt", "r", stdin);
    int op, x, y, a, l, b, r, t;
    memset(tree, 0, sizeof(tree));
    while(1)
    {
        scanf("%d", &op);
        if(op == 0) scanf("%d", &n);
        else if(op == 1)
        {
            scanf("%d%d%d", &x, &y, &a);
            update(++x, ++y, a);
        }
        else if(op == 2)
        {
            scanf("%d%d%d%d", &l, &b, &r, &t);
            l++;
            b++;
            r++;
            t++;
            printf("%d\n", sum(r, t)-sum(l-1, t)-sum(r, b-1)+sum(l-1, b-1));
        }
        else if(op == 3) break;
    }
    return 0;
}


你可能感兴趣的:(poj,数据结构-线段树&树状数组)