zoukankan      html  css  js  c++  java
  • 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 } 

  • 相关阅读:
    Oracle 分区索引
    linux中select网络通信
    AVL树,红黑树,B-B+树,Trie树原理和应用
    zoj1232Adventure of Super Mario(图上dp)
    怎样更改Linux中默认的openjdk为自己安装的JDK
    食用甜玉米:增进健康,老少皆宜
    设计模式【3】:抽象工厂【创建对象】
    centos 7 安装JDK (Linux安装jdk)
    微信支付v3开发(5) 扫码并输入金额支付
    微信支付v3开发(6) 收货地址共享接口
  • 原文地址:https://www.cnblogs.com/acvc/p/3581251.html
Copyright © 2011-2022 走看看