zoukankan      html  css  js  c++  java
  • POJ

    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

    题意:在N*N的矩阵中,输入0为清空数组,输入1为改变坐标x,y处的值,输入2为查询区域x1,y1到x2,y2的所有值总和,标准的二维树状数组模板题。
    只需在更新时修改数组坐标位置的和,然后向上更新即可。
    查询只需要利用容斥原理将相应区域位置的四个坐标做前缀和的求和和多余区域的删减,以及重复删除区域的加和即可得到最终所求区域的总和。

    #include<stdio.h>///二维树状数组模板题
    #include<string.h>
    #define LL long long
    LL tre[1036][1036];
    int n;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int y,int add)///区间更新,对被更新区域前缀和更新x到y更新至n 增长率为lowbit(i)
    {
        for(int i=x; i<=n; i+=lowbit(i))
            for(int j=y; j<=n; j+=lowbit(j))
                tre[i][j]+=add;
    
    }
    LL sum(int x,int y)///求和
    {
        LL sum=0;
        for(int i=x; i>0; i-=lowbit(i))
            for(int j=y; j>0; j-=lowbit(j))
                sum+=tre[i][j];
        return sum;
    }
    int main()
    {
        int flag;
        while(scanf("%d",&flag)!=EOF)
        {
            if(flag==0)///输入0时清空数组
            {
                memset(tre,0,sizeof(tre));
                scanf("%d",&n);
            }
            else if(flag==1)///输入1时做单点修改
            {
                int x,y,add;
                scanf("%d%d%d",&x,&y,&add);
                x++;y++;///注意题目是从0,0的坐标开始的,直到n-1,而树状数组因为要lowbit操作必从1开始n结束,因此在输入后应+1表示树状数组中存储的位置
                update(x,y,add);
            }
            else if(flag==2)///输入2时区间求和查询
            {
                int x1,y1,x2,y2;
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                x1++;y1++;x2++;y2++;
                printf("%lld
    ",sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1));///容斥原理删减增加重复减去的内容
            }
            else break;
        }
    }
    
  • 相关阅读:
    链表重排 【模板题】
    链表的插入排序
    链表归并排序
    判断链表成环| 删除第K个节点【快慢指针】
    vue骨架屏制作
    前端常用的网站+插件
    点击canvas图片下载图片
    判断dom是否出现在可视区域
    canvas截取图片
    .如果在input上加上@keyup.enter.native,第一次回车时还是会刷新界面,在el-from上加上 @submit.native.prevent
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135831.html
Copyright © 2011-2022 走看看