Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 14288 | Accepted: 6642 |
Description
Input
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 |
#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; }