1. 程式人生 > >POJ1195 Mobile phones 【二維樹狀數組】

POJ1195 Mobile phones 【二維樹狀數組】

chan mono ins written writing ram cor data- amp

Mobile phones
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 14288 Accepted: 6642

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 contains a base station. The number of active mobile phones inside a square can change because a phone is moved from a square to another or a phone is switched on or off. At times, each base station reports the change in the number of active phones to the main base station along with the row and the column of the matrix.

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 input is read from standard input as integers and the answers to the queries are written to standard output as integers. The input is encoded as follows. Each input comes on a separate line, and consists of one instruction integer and a number of parameter integers according to the following table.
技術分享

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

Your program should not answer anything to lines with an instruction other than 2. If the instruction is 2, then your program is expected to answer the query by writing the answer as a single line containing a single integer to standard 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

方格(XY)內的開機移動電話量添加了AA可能是正數也可能是負數

2

L B R T

詢問在矩形區域(L,B)(R,T)內有多少部開機的移動電話。矩形區域(L,B)(R,T)包含全部的格子(XY)滿足L<=X<=R,B<=Y<=T.

3

終止程序。

這個指令僅僅會在最後出現一次。

全部的數據總是在給定範圍內,你不須要差錯。

特別的,假設A是負數,你能夠覺得該操作不會讓該格子的開機移動電話數變成負數。格子是從0開始編號的,比方一個4*4的區域,全部的格子(XY)應該表示為: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 【二維樹狀數組】