首页 > 代码库 > POJ1195 Mobile phones 【二维树状数组】
POJ1195 Mobile phones 【二维树状数组】
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 14288 | Accepted: 6642 |
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
【问题描写叙述】
如果第四代移动电话的收发站是这样执行。整个区域被切割成非常小的方格。全部的方格组成了一个S*S的矩阵,行和列从0~S-1编号。每一个小方格都包括一个收发站。每一个方格内的手机的移动电话数量能够不断改变,由于手机用户在各个方格之间移动,也实用户开机或者关机。一旦某个方格里面开机的移动电话数量发生了变化,该方格里的收发站就会向总部发送一条信息说明这个改变量。
总部要你写一个程序,用来管理从各个收发站收到的信息。老板可能随时会问:某个给定矩形区域内有多少部开机的移动电话啊?你的程序必需要能随时回答老板的问题。
【输入输出数据】
从标准输入读入整数,向标准输出写入你对老板的回答。
输入数据的格式例如以下:每一个输入独立成一行。一个输入包含一个指示数和一些參数,见下表:
指示数 |
參数 |
意义 |
0 |
S |
初始指令。整个区域由S*S个小方格组成。这个指令仅仅会在一開始出现一次。 |
1 |
X Y A |
方格(X,Y)内的开机移动电话量添加了A。A可能是正数也可能是负数 |
2 |
L B R T |
询问在矩形区域(L,B)—(R,T)内有多少部开机的移动电话。矩形区域(L,B)—(R,T)包含全部的格子(X。Y)满足L<=X<=R,B<=Y<=T. |
3 |
|
终止程序。 这个指令仅仅会在最后出现一次。 |
全部的数据总是在给定范围内,你不须要差错。
特别的,假设A是负数,你能够觉得该操作不会让该格子的开机移动电话数变成负数。格子是从0開始编号的,比方一个4*4的区域,全部的格子(X,Y)应该表示为:0<=X<=3,0<=Y<=3。
对于除了2之外的指示,你的程序不应该输出不论什么东西。
假设指示是2。那么你的程序应该向标准输出写入一个整数。
【数据限制】
区域大小 |
S * S |
1 * 1 <= S * S <= 1024 * 1024 |
每一个格子的值 |
V |
0 <= V <= 32767 |
添加/降低量 |
A |
-32768 <= A <= 32767 |
指令总数 |
U |
3 <= U <= 60002 |
全部格子的和 |
M |
M= 2^30 |
第一次在OJ题中用函数指针数组。感觉挺简洁的。
#include <stdio.h> int tree[1030][1030], size; int lowBit(int n) { return n & (-n); } void getSize() { scanf("%d", &size); } void update() { int x, y, val; scanf("%d%d%d", &x, &y, &val); ++x; ++y; int temp; while(x <= size){ temp = y; while(temp <= size){ tree[x][temp] += val; temp += lowBit(temp); } x += lowBit(x); } } int getSum(int x, int y) { int sum = 0, temp; while(x > 0){ temp = y; while(temp > 0){ sum += tree[x][temp]; temp -= lowBit(temp); } x -= lowBit(x); } return sum; } void query() { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); ++x1; ++y1; ++x2; ++y2; int sum = getSum(x2, y2) - getSum(x2, y1 - 1) - getSum(x1 - 1, y2) + getSum(x1 - 1, y1 - 1); printf("%d\n", sum); } void (*funArr[])() = { getSize, update, query }; //函数指针数组 int main() { int com; while(scanf("%d", &com), com != 3) (*funArr[com])(); return 0; }
POJ1195 Mobile phones 【二维树状数组】