题解报告:poj 1195 Mobile phones(二维BIT裸题)
Description
Write a program, which receives these reports and answers queries about the current total number of active mobile phones in any rectangle-shaped area.
Input

The values will always be in range, so there is no need to check them. In particular, if A is negative, it can be assumed that it will not reduce the square value below zero. The indexing starts at 0, e.g. for a table of size 4 * 4, we have 0 <= X <= 3 and 0 <= Y <= 3.
Table size: 1 * 1 <= S * S <= 1024 * 1024
Cell value V at any time: 0 <= V <= 32767
Update amount: -32768 <= A <= 32767
No of instructions in input: 3 <= U <= 60002
Maximum number of phones in the whole table: M= 2^30
Output
Sample Input
0 4
1 1 2 3
2 0 0 2 2
1 1 1 2
1 1 2 -1
2 1 1 2 3
3
Sample Output
3
4
解题思路:这是一道二维树状数组入门题---单点修改、单点(区间)查询,其思路和一维树状数组非常相似,多加了一个维度而已。下面我们来看看怎么实现这两个基本操作:
将一维数组A[]扩展到二维数组A[][],二维树状数组C[][]来维护矩阵前缀和。
设原始二维数组A[][]={a11,a12,a13,a14,a15,
a21,a22,a23,a24,a25,
a31,a32,a33,a34,a35,
a41,a42,a43,a44,a45,
a51,a52,a53,a54,a55};
那么二维树状数组表示如下:
C[1][]=a1,C[1][]=a1+a1,C[1][]=a1,C[1][]=a1+a1+a1+a1,C[1][]=a15
这是数组A[][]第一行的一维树状数组;
C[][1]=a1+a1,C[][]=a1+a+a+a,C[][]=a+a,C[][]=a+a+a+a+a+a+a+a,C[][]=a+a5
这是数组A[][]第一行和第二行相加后得到的树状数组;
C[3][]=a3,C[3][]=a3+a3,C[3][]=a3,C[3][]=a3+a3+a3+a3,C[3][]=a35
这是数组A[][]第三行的一维树状数组;
C[][]=a+a+a+a,C[][]=a+a+a+a+a+a+a+a,C[][]=a+a+a+a...
这是数组A[][]前4行相加后得到的树状数组;
C[5][]=a5,C[5][]=a5+a5,C[5][]=a5,C[5][]=a5+a5+a5+a5,C[5][]=a55
这是数组A[][]第5行的一维树状数组。
仔细观察以上式子可以发现,二维树状数组C[x][y]的值其实是分别在x、y上的一维树状数组向下、向右(x上+lowbit(x)跳跃(>n停止),y上+lowbit(y)跳跃(>n停止))进行求和,这就是矩阵中坐标点值的单点修改。对于区间查询,同样分别在x、y上的一维树状数组从下往上,从右往左进行累加(y上-lowbit(y)跳跃(<=0停止),x上-lowbit(x)跳跃(<=0停止)),这样就得到了(1,1)到(x,y)矩阵中所有元素的和。
回到本题,题意为给出一些命令进行一些操作:
0 S 初始化一个全0的S*S矩阵,这个命令只会在第一次给出一次;
1 X Y A 给坐标点(X,Y)的值加上A;
2 L B R T 询问(L,B)到(R,T)构成的矩阵中所有元素的总和;
3 结束对矩阵的操作,程序终止。
典型的二维BIT,套一下模板即可,但需要注意一点:给出命令中的坐标都是默认从下标0开始的,为避免陷入死循环和计算错误,在更新和询问操作上统一对每一个坐标点(横、纵坐标)加1。
怎么统计坐标点(L,B)到(R,T)矩阵内所有值呢?给出下面的矩阵:
1 2 3 4 5
1 0 0 0 0 0
2 0 0 0 0 0
3 0 0 0
4 0 0 0
5 0 0 0 0
从图上可得计算公式:[R,T]-[L-1,T]-[R,B-1]+[L-1,B-1](多减去了一个左上角的矩阵,还要把它加回来),这样就得到了点(L,B)到(R,T)矩阵中所有元素的和。
AC代码:
#include<cstdio>
#include<string.h>
const int maxn=;
int op,s,x,y,a,l,b,r,t,C[maxn][maxn];
void add(int x,int y,int val){//单点修改
for(int i=x;i<=s;i+=i&-i)
for(int j=y;j<=s;j+=j&-j)
C[i][j]+=val;
}
int query(int x,int y){//前缀和查询
int ans=;
for(int i=x;i>;i-=i&-i)
for(int j=y;j>;j-=j&-j)
ans+=C[i][j];
return ans;
}
int main(){
while(~scanf("%d%d",&op,&s)){
memset(C,,sizeof(C));
while(~scanf("%d",&op)&&op!=){
if(op==){
scanf("%d%d%d",&x,&y,&a);
x++,y++;add(x,y,a);//单点修改
}
else{
scanf("%d%d%d%d",&l,&b,&r,&t);l++,b++,r++,t++;
printf("%d\n",query(r,t)-query(l-,t)-query(r,b-)+query(l-,b-));//区间查询,求矩形中所有元素的和
}
}
}
return ;
}
题解报告:poj 1195 Mobile phones(二维BIT裸题)的更多相关文章
- poj 1195 Mobile phones(二维树状数组)
树状数组支持两种操作: Add(x, d)操作: 让a[x]增加d. Query(L,R): 计算 a[L]+a[L+1]……a[R]. 当要频繁的对数组元素进行修改,同时又要频繁的查询数组内任一 ...
- poj 1195:Mobile phones(二维树状数组,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14489 Accepted: 6735 De ...
- poj 1195:Mobile phones(二维线段树,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14391 Accepted: 6685 De ...
- (简单) POJ 1195 Mobile phones,二维树状数组。
Description Suppose that the fourth generation mobile phone base stations in the Tampere area operat ...
- POJ 1195 Mobile phones(二维树状数组)
Mobile phones Time Limit: 5000MS Mem ...
- POJ 1195 Mobile phones (二维树状数组)
Description Suppose that the fourth generation mobile phone base stations in the Tampere area operat ...
- POJ 1195:Mobile phones 二维树状数组
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 16893 Accepted: 7789 De ...
- POJ 1195 Mobile phones【二维树状数组】
<题目链接> 题目大意: 一个由数字构成的大矩阵,开始是全0,能进行两种操作1) 对矩阵里的某个数加上一个整数(可正可负)2) 查询某个子矩阵里所有数字的和要求对每次查询,输出结果 解题分 ...
- POJ 1195 Mobile phones【 二维树状数组 】
题意:基础的二维数组,注意 0 + lowbit(0)会陷入无限循环----- 之前做一道一维的一直tle,就是因为这个-------------------------- #include<i ...
随机推荐
- Download Software Top 10
We are quite rich in terms of web browsers! Nevertheless, it's a bit surprising to know that even so ...
- curl_setopt GET的方法
$ch ") ; curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; curl_setopt($ch, CURLOPT_BINARYTRANSF ...
- php事务操作示例
<?php //数据库连接 $conn = mysql_connect('localhost', 'root', '');mysql_select_db('test', $conn); /* 支 ...
- POI 的使用
POI 使用 一. POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能..NET的开发人员则 ...
- Redis系列之-—Redis-cli命令总结【转】
Redis-cli命令最新总结 参考资料: http://redisdoc.com/ 或者 http://doc.redisfans.com http://redis.io/commands 一. 进 ...
- 开发:异常收集之 DB2建表相关问题
第一次用DB2数据库,因为考虑到建表语句可能不一样,所以採用手动建表的办法.一个个字段去填.并勾选主键.最后发现创建失败.看了下系统生成的sql语句 sql语句例如以下: CREATE TABLE F ...
- Python函数参数传递
Python中函数参数的传递是采用传值方式,但是和C/C++有所不同 C/C++方式 void fun(int a) { a = 10; } void main() { int c =3; fun(c ...
- 一个程序员对微信小程序的看法
我们公司用两周的时间开发了一款微信小程序,叫<如e支付>,大家可以去体验一下.由于接口都是写好的,所以开发起来很快.我将从4个不同的角度来介绍我对微信小程序的理解. 1.技术的角度 ...
- Apache Karaf配置远程调试
软件环境 apache-karaf-4.0.0 配置方法: 在 bin/karaf.bat 文件里,顶部增加 set KARAF_DEBUG=true 然后.重新启动karaf 启动之后.就可以看到例 ...
- Android开发系列(二十七):使用ProgressDialog创建进度对话框
进度对话框在寻常的应用中非经常见,比方下载的时候,打开页面的时候.转移文件等等.有环形的.有长条形的. 基本就这两种 创建进度对话框的两种方式: 1.创建ProgressDialog实例,然后调用Pr ...