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

题目链接:POJ 1195

题意:

  给出一个S*S的矩阵(行、列号从1开始),每个元素初始值为0,有两种操作:一种是第X行第Y列元素值加A;另一种是查询给定范围矩阵的所有元素之和(L<=X<=R,B<=Y<=T)。

分析:

  查询给定范围矩阵的所有元素之和是二维区间和,可以转换为二维前缀和求值。类比一维前缀和求法,二维区间和S(L, B, R, T) = S(1, 1, R, T) - S(1 ,1, L-1, T) - S(1, 1, R, B-1) + S(1, 1, L-1, B-1)。单点更新一个元素的值,修改二维前缀和,类比一维树状数组的更新操作,二维树状数组的更新操作(参考代码)。

总结:

  二维树状数组可以理解为:先固定X=i,把Y=1~S看作一维树状数组就比较容易理解,再X=1~S看作一维树状数组,这样组合成二维树状数组。如果还想不明白,可以想想二元积分是怎么做的。

代码实现:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int N = 1024 + 5;
int C[N][N], cmd, s, x, y, a, l, b, r, t;

int lowbit(int x)
{
    return x & (-x);
}
void add(int x, int y, int a)
{
    for (int i = x; i <= s; i += lowbit(i))
        for (int j = y; j <= s; j += lowbit(j))
            C[i][j] += a;
}
int sum(int x, int y)
{
    int ret = 0;
    for (int i = x; i; i -= lowbit(i))
        for (int j = y; j; j -= lowbit(j))
            ret += C[i][j];
    return ret;
}
int main()
{
    while (~scanf("%d", &cmd)) {
        if (cmd == 3) break;
        if (cmd == 0) {
            scanf("%d", &s);
            for (int i = 1; i <= s; i++)
                for (int j = 1; j <= s; j++)
                    C[i][j] = 0;
            continue;
        }
        if (cmd == 1) {
            scanf("%d%d%d", &x, &y, &a);
            x++, y++;
            add(x, y, a);
            continue;
        }
        if (cmd == 2) {
            scanf("%d%d%d%d", &l, &b, &r, &t);
            l++, b++, r++, t++;
            int ans = sum(r, t) - sum(l-1, t) - sum(r, b-1) + sum(l-1, b-1);
            printf("%d\n", ans);
        }
    }
    return 0;
}

  

时间: 2024-10-03 13:46:19

POJ 1195 Mobile phones(二维树状数组)的相关文章

POJ1195 Mobile phones 二维树状数组的应用

这题可以用线段树离散化做,用二维树状数组做了一下,不懂得可以看一下这篇文章:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804 题意: 给你一个s*s的正方形区域,先输入一个x,若x==0,则再输入一个s,若x==1,则输入x,y,a,表示矩阵中(x,y)这点的值加上a,若x==2,输入l,b,r,t,代表以左上角的点(l,b)右下角的点(r,t),求这一片矩形内的矩阵元素之和,若x==3则结束此次程序 就是最基

POJ1195:Mobile phones(二维树状数组)

Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The squares form an S * S matrix with the rows and columns numbered from 0 to S-1. Each square contain

【poj1195】Mobile phones(二维树状数组)

题目链接:http://poj.org/problem?id=1195 [题意] 给出一个全0的矩阵,然后一些操作 0 S:初始化矩阵,维数是S*S,值全为0,这个操作只有最开始出现一次 1 X Y A:对于矩阵的X,Y坐标增加A 2 L B R T:询问(L,B)到(R,T)区间内值的总和 3:结束对这个矩阵的操作 [思路] 二维树状数组单点更新+区域查询,可作为模板题. 注意坐标是从0开始,所以要+1 [代码] 1 #include<cstdio> 2 #include<cstrin

POJ 2155 Matrix 【二维树状数组】

题目链接:http://poj.org/problem?id=2155 题目大意:给出一个N*N的0矩阵,下面给出两种指令:1. 给出的第一个数据为'C',再给出四个整形数据,x1,y1,y1,y2,对以(x1,y1)(x2,y2)分别为左上角和右下角坐标的矩阵内的元素进行反转(0变1,1变0)         2. 给出的第一个数据为'Q',再给出两个数据,x,y,然后输出此时这个坐标上的元素. 这题用二维树状数组解,树状数组能够对某区间更新所有元素的和,树状数组维护的是c[1][1]到c[i

POJ 1195-Mobile phones(二维树状数组-区间更新区间查询)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 17661   Accepted: 8173 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The

POJ 2155 Matrix【二维树状数组+YY(区间更新,单点查询)】

题目链接:http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 32950   Accepted: 11943 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th col

Mobile phones_二维树状数组

[题意]给你一个矩阵(初始化为0)和一些操作,1 x y a表示在arr[x][y]加上a,2 l b r t 表示求左上角为(l,b),右下角为(r,t)的矩阵的和. [思路]帮助更好理解树状数组. #include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int N=1050; int c[N][N]; int s; int lowbit(int x) { r

POJ 2155 Matrix(二维树状数组)

题意:有一个矩阵,每次操作可以是编辑某个矩形区域,这个区域的0改为1,1改为0,每次查询只查询某一个点的值是0还是1.  思路:这道题和一般的树状数组有一点不同,这道题是区间修改,单点查询,而树状数组处理的是单点修改,所以我们可以改一下矩阵里的每一个值代表的意义.可以注意到我们只关注一个点被翻转了奇数次还是偶数次,令矩阵的元素a[i][j]表示矩形区域(1,1)到(i,j)的修改次数,这样我们可以把区间修改转化为四个端点的单点修改,即modify(x2, y2, 1); modify(x1-

poj 1195 Mobile phones(二维数组)

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int c[1048][1048],n; int lowbit[1048]; void add(int x,int y,int d) { int i,j; for(i=x;i<=n;i+=lowbit[i]) for(j=y;j<=n;j+=lowbit[j]) { c[i][j]+=d; } } int

POJ 题目2155 Matrix(二维树状数组)

Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20303   Accepted: 7580 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1