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;
}