zoukankan      html  css  js  c++  java
  • POJ 1195 Mobile phones

    链接:http://poj.org/problem?id=1195


    Mobile phones
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 16646   Accepted: 7653

    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


    Source


    大意——给你一个n*n矩阵的区域,它的行列下标都是从0開始的。每一个矩阵元素代表一个基站。基站内的处于执行中的手机数量由于各种原因会不断变化。各个基站会不定期地向主基站报告,以便统计执行中的手机数量。你的任务是依据对应的命令完毕对应的操作。

    当中基本的就是更新某一个矩阵元素的值和一个区域的矩阵元素值之和。


    思路——非常显然这是一个裸的二维树状数组的题。

    其操作就是更新某一个值和区间求和。因此。我们直接用一维树状数组推广过来就可以解决这个问题。注意:矩阵元素下标从0開始。


    复杂度分析——时间复杂度:O((log(n))^2),空间复杂度:O(n^2)


    附上AC代码:


    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cmath>
    #include <iomanip>
    #include <ctime>
    #include <climits>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <set>
    #include <map>
    //#pragma comment(linker, "/STACK:102400000, 102400000")
    using namespace std;
    typedef unsigned int li;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    const double pi = acos(-1.0);
    const double e = exp(1.0);
    const double eps = 1e-8;
    const int maxn = 1030;
    int mat[maxn][maxn];
    int order; // 键入命令
    int n; // 数组大小
    
    int lowbit(int x); // 求2^k,k表示x为二进制时末尾的零的个数
    void update(int x, int y, int add); // 更新状态
    int sum(int x, int y); // 求和
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	int x1, y1, x2, y2, add, ans;
    	while (scanf("%d", &order)==1 && 3!=order)
    	{
    		switch(order)
    		{
    			case 0:
    				scanf("%d", &n);
    				memset(mat, 0, sizeof(mat)); // 初始化为0
    				break;
    			case 1:
    				scanf("%d%d%d", &x1, &y1, &add);
    				update(x1+1, y1+1, add); // x,y可能为0,所以加1。后面相似
    				break;
    			case 2:
    				scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    				ans = 0;
    				ans += sum(x2+1, y2+1); // 总求和
    				ans -= sum(x2+1, y1);
    				ans -= sum(x1, y2+1); // 去掉多余部分
    				ans += sum(x1, y1); // 多减掉一部分,加回来。绘图可知
    				printf("%d
    ", ans);
    				break;
    			default:
    				printf("INPUT ERROR!
    ");
    				break;
    		}
    	}
    	return 0;
    }
    
    int lowbit(int x)
    {
    	return (x&(-x));
    }
    
    void update(int x, int y, int add)
    { // x,y表示矩阵下标,此功能是把下标为x。y的数加上add
    	for (int i=x; i!=0&&i<=n; i+=lowbit(i))
    		for (int j=y; j!=0&&j<=n; j+=lowbit(j))
    			mat[i][j] += add;
    }
    
    int sum(int x, int y)
    { // x。y表示矩阵下标,此功能是把下标小于x,y的矩阵元素值加起来
    	int res = 0;
    	for (int i=x; i>0; i-=lowbit(i))
    		for (int j=y; j>0; j-=lowbit(j))
    			res += mat[i][j];
    	return res;
    }
    


  • 相关阅读:
    Week7 作业 A
    Mouth 1 模拟题 CSP201512-3 画图
    C++出现:error: passing 'const Employee' as 'this' argument of 'int Employee::getSalary()' discards qualifiers [-fpermissive]
    C++出现error: no match for call to '(MyCompare) (const key_type&, const Person&)'
    CentOS 7出现ifconfig:command not found
    有效清理C盘内存
    重装系统之后出现https:/ / logincdn.msauth.net/shared/1.0/content/js/ConvergedLogin_PCore_xxvbETmiVPe1AsI9xwHp3A2.js
    C++/QT运行时出现void value not ignored as it ought to be
    运行QT项目文件夹下的exe文件提示找不到“各种dll”
    Ubuntu16.04配置OpenCV3.2.0
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7239482.html
Copyright © 2011-2022 走看看