• Codeforces Round #219 (Div. 2) D题


    D. Counting Rectangles is Fun
    time limit per test
    4 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    There is an n × m rectangular grid, each cell of the grid contains a single integer: zero or one. Let's call the cell on the i-th row and the j-th column as (i, j).

    Let's define a "rectangle" as four integers a, b, c, d (1 ≤ a ≤ c ≤ n; 1 ≤ b ≤ d ≤ m). Rectangle denotes a set of cells of the grid {(x, y) :  a ≤ x ≤ c, b ≤ y ≤ d}. Let's define a "good rectangle" as a rectangle that includes only the cells with zeros.

    You should answer the following q queries: calculate the number of good rectangles all of which cells are in the given rectangle.

    Input

    There are three integers in the first line: nm and q (1 ≤ n, m ≤ 40, 1 ≤ q ≤ 3·105). Each of the next n lines contains m characters — the grid. Consider grid rows are numbered from top to bottom, and grid columns are numbered from left to right. Both columns and rows are numbered starting from 1.

    Each of the next q lines contains a query — four integers that describe the current rectangle, abcd (1 ≤ a ≤ c ≤ n; 1 ≤ b ≤ d ≤ m).

    Output

    For each query output an answer — a single integer in a separate line.

    Sample test(s)
    input
    5 5 5
    00101
    00000
    00001
    01000
    00001
    1 2 2 4
    4 5 4 5
    1 2 5 2
    2 2 4 5
    4 2 5 3
    output
    10
    1
    7
    34
    5
    input
    4 7 5
    0000100
    0000010
    0011000
    0000000
    1 7 2 7
    3 1 3 1
    2 3 4 5
    1 2 2 7
    2 2 4 7
    output
    3
    1
    16
    27
    52

     //题意:给出一个矩阵每次输入给出查询的范围a,b,c,d求出范围内由0做成的的矩形的个数

    sol: 矩阵上的dp,可以这么想例如是1维的给出:000111000,dp方程很容易dp[i] = dp[i-1]+sum[i]; 为什么,加上前缀和嫩? 可以验证一下每次向后移动一位则增加的矩阵数目为当前位和前面每一位组成的矩形加上当前的矩形,正好是前缀和(fuck-理解了好久),转换到二维上就容易了,同样是矩阵从小到大枚举

     1 #include <cstdio>
     2 #include <vector>
     3 #include <set>
     4 #include <algorithm>
     5 using namespace std;
     6 //using PII = pair<int,int>;
     7 //using LL = long long;
     8 const int INF = 1000000007;
     9 
    10 int a[45][45],cnt[45][45][45][45];
    11 int s[45][45],sum[45][45][45][45];
    12 
    13 int main(){
    14     int n,m,cs;
    15     scanf("%d%d%d",&n,&m,&cs);
    16     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
    17         scanf("%1d",&a[i][j]);
    18         s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
    19       //  printf("%d %d %d ",i,j,s[i][j]);
    20     }
    21     for(int i=n;i>=1;i--) for(int j=m;j>=1;j--)
    22     for(int r=i;r<=n;r++) for(int c=j;c<=m;c++){
    23         int dot=s[r][c]-s[r][j-1]-s[i-1][c]+s[i-1][j-1];
    24      //   printf("%d %d %d %d %d ",i,j,r,c,dot);
    25         cnt[i][j][r][c]=cnt[i][j][r-1][c]+cnt[i][j][r][c-1]-cnt[i][j][r-1][c-1]+!dot;
    26     }
    27     for(int i=n;i>=1;i--) for(int j=m;j>=1;j--)
    28     for(int r=i;r<=n;r++) for(int c=j;c<=m;c++)
    29         sum[i][j][r][c]=sum[i+1][j][r][c]+sum[i][j+1][r][c]-sum[i+1][j+1][r][c]+cnt[i][j][r][c];
    30     while(cs--)
    31     {
    32         int a,b,c,d;
    33         scanf("%d%d%d%d",&a,&b,&c,&d);
    34         printf("%d ",sum[a][b][c][d]);
    35     }

    36 } 

  • 相关阅读:
    反射
    定义类
    集合list,set,Map
    API util
    进程与多线程
    泛型
    API string
    JDBC存储过程
    预处理
    JDBC
  • 原文地址:https://www.cnblogs.com/acvc/p/3581251.html
Copyright © 2020-2023  润新知