• 2018 Multi-University Training Contest 4 Problem E. Matrix from Arrays 【打表+二维前缀和】


    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6336

    Problem E. Matrix from Arrays

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 1711    Accepted Submission(s): 794


    Problem Description
    Kazari has an array A length of L, she plans to generate an infinite matrix M using A.
    The procedure is given below in C/C++:

    int cursor = 0;
    for (int i = 0; ; ++i) {
    for (int j = 0; j <= i; ++j) {
    M[j][i - j] = A[cursor];
    cursor = (cursor + 1) % L;
    }
    }


    Her friends don't believe that she has the ability to generate such a huge matrix, so they come up with a lot of queries about M, each of which focus the sum over some sub matrix. Kazari hates to spend time on these boring queries. She asks you, an excellent coder, to help her solve these queries.
     
    Input
    The first line of the input contains an integer T (1T100) denoting the number of test cases.
    Each test case starts with an integer L (1L10) denoting the length of A.
    The second line contains L integers A0,A1,...,AL1 (1Ai100).
    The third line contains an integer Q (1Q100) denoting the number of queries.
    Each of next Q lines consists of four integers x0,y0,x1,y1 (0x0x1108,0y0y1108) querying the sum over the sub matrix whose upper-leftmost cell is (x0,y0) and lower-rightest cell is (x1,y1).
     
    Output
    For each test case, print an integer representing the sum over the specific sub matrix for each query.
    Sample Input
    1
    3
    1 10 100
    5
    3 3 3 3
    2 3 3 3
    2 3 5 8
    5 1 10 10
    9 99 999 1000
     
    Sample Output
    1
    101
    1068
    2238
    33076541
     
    Source

    题意概括:

    给一个长度为 L 的序列,要求按照代码的要求构建一个矩阵。

    Q次查询,每次查询输入矩阵的左上角和右下角坐标,输出矩阵的值的总和。

    解题思路:

    并没有什么过人的天分,老老实实把构建的矩阵输出来找规律。

    发现大矩阵是长宽 为 2*L 的小矩阵构造而成的。

    问题就转换为了类似于求矩阵面积的问题,也就可以通过二维前缀和 sum(x, y) 来求解答案。

    例如要求解 (x1, y1, x2, y2) 的值就等于 sum(x2, y2) - sum(x1-1, y2) - sum(x2, y1-1) + sum(x1-1, y1-1);

    如何计算 sum(x, y)呢?首先统计有多少个 2L * 2L 的子矩阵,然后再单独加上这些除掉这些子矩阵的其余部分。

    AC code:

     1 #include<set>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstring>
     6 #include<vector>
     7 #include<queue>
     8 #include<cmath>
     9 #define INF 0x3f3f3f3f
    10 #define LL long long
    11 using namespace std;
    12 const int MAXN = 1e3+10;
    13 LL sum;
    14 int mmp[MAXN][MAXN];
    15 int N, M, L, Q;
    16 LL sum1[MAXN], sum2[MAXN];
    17 int A[MAXN];
    18 
    19 void init()
    20 {
    21     memset(mmp, 0, sizeof(mmp));
    22     memset(sum1, 0, sizeof(sum1));
    23     memset(sum2, 0, sizeof(sum2));
    24     int cnt = 0;
    25     for(int i = 0; i < 4*L; i++){
    26         for(int j = 0; j <= i; j++){
    27             mmp[j][i-j] = A[cnt];
    28             cnt = (cnt+1)%L;
    29         }
    30     }
    31     sum = 0;
    32     for(int i = 0; i < 2*L; i++){
    33         for(int j = 0; j < 2*L; j++){
    34             sum+=mmp[i][j];
    35             sum1[i] += mmp[i][j];
    36             sum2[j] += mmp[i][j];
    37         }
    38     }
    39 }
    40 
    41 LL query(int x, int y)
    42 {
    43     int cnt_x = (x+1)/(2*L);
    44     int cnt_y = (y+1)/(2*L);
    45     LL res = sum*cnt_x*cnt_y;
    46     int lenx = (x+1)%(2*L);
    47     int leny = (y+1)%(2*L);
    48 
    49     for(int i = 0; i < lenx; i++) res+= cnt_y*sum1[i];
    50     for(int j = 0; j < leny; j++) res+= cnt_x*sum2[j];
    51     
    52 
    53     for(int i = 0; i < lenx; i++)
    54         for(int j = 0; j < leny; j++){
    55             res+=mmp[i][j];
    56         }
    57 
    58     return res;
    59 }
    60 
    61 int main()
    62 {
    63     int T_case;
    64     int x1, x2, y1, y2;
    65     scanf("%d", &T_case);
    66     while(T_case--){
    67         scanf("%d", &L);
    68         for(int i = 0; i < L; i++){
    69             scanf("%d", &A[i]);
    70         }
    71         init();
    72         
    73         scanf("%d", &Q);
    74         while(Q--){
    75             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
    76             LL ans = query(x2, y2)-query(x1-1, y2) - query(x2, y1-1) + query(x1-1, y1-1);
    77             printf("%lld
    ", ans);
    78         }
    79     }
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    【leetcode】Remove Duplicates from Sorted Array I & II(middle)
    Android--Activity在跳转时携带数据
    HDU 5371 Manacher
    Java之旅hibernate(2)——文件夹结构
    【智能路由器】让MT7620固件openwrt支持USB
    Android Context 是什么?
    分治法解决高速排序问题
    Alluxio增强Spark和MapReduce存储能力
    UVA
    《React-Native系列》44、基于多个TextInput的键盘遮挡处理方案优化
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10334522.html
Copyright © 2020-2023  润新知