zoukankan      html  css  js  c++  java
  • Codeforces Round #371 (Div. 1) D. Animals and Puzzle 二维倍增

    D. Animals and Puzzle

    题目连接:

    http://codeforces.com/contest/713/problem/D

    Description

    Owl Sonya gave a huge lake puzzle of size n × m to hedgehog Filya as a birthday present. Friends immediately started to assemble the puzzle, but some parts of it turned out to be empty — there was no picture on them. Parts with picture on it are denoted by 1, while empty parts are denoted by 0. Rows of the puzzle are numbered from top to bottom with integers from 1 to n, while columns are numbered from left to right with integers from 1 to m.

    Animals decided to complete the picture and play with it, as it might be even more fun! Owl and hedgehog ask each other some queries. Each query is provided by four integers x1, y1, x2, y2 which define the rectangle, where (x1, y1) stands for the coordinates of the up left cell of the rectangle, while (x2, y2) stands for the coordinates of the bottom right cell. The answer to the query is the size of the maximum square consisting of picture parts only (only parts denoted by 1) and located fully inside the query rectangle.

    Help Sonya and Filya answer t queries.

    Input

    The first line of the input contains two integers n and m (1 ≤ n, m ≤ 1000) — sizes of the puzzle.

    Each of the following n lines contains m integers aij. Each of them is equal to 1 if the corresponding cell contains a picture and 0 if it's empty.

    Next line contains an integer t (1 ≤ t ≤ 1 000 000) — the number of queries.

    Then follow t lines with queries' descriptions. Each of them contains four integers x1, y1, x2, y2 (1 ≤ x1 ≤ x2 ≤ n, 1 ≤ y1 ≤ y2 ≤ m) — coordinates of the up left and bottom right cells of the query rectangle.

    Output

    Print t lines. The i-th of them should contain the maximum size of the square consisting of 1-s and lying fully inside the query rectangle

    Sample Input

    3 4
    1 1 0 1
    0 1 1 0
    0 1 1 0
    5
    1 1 2 3
    2 1 3 2
    3 2 3 4
    1 1 3 4
    1 2 3 4

    Sample Output

    1
    1
    1
    2
    2

    Hint

    题意

    给你一个01矩阵,然后Q次询问,每次询问一个矩形区域中,最大的全一正方形的边长是多少。

    题解:

    此题分为两部分:

    1.求出以每个点为右下角的最大正方形边长。

    2.二分答案

    第一个部分用dp即可,应该不难吧dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1。

    第二个部分,假如要求有没有边长为len的正方形,左上角有一部分点的边长肯定不合法,合法区间为(x1+len-1,y1+len-1)~(x2,y2),用二维倍增求最大值即可。

    二维线段树也是可以的,我只后再补上。

    代码

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 using namespace std;
     6 #define ll long long
     7 #define N 1005
     8 int n,m,x1,y1,x2,y2;
     9 int dp[N][N],mx[N][N][10][10],mm[N];
    10 template<typename T>void read(T&x)
    11 {
    12     ll k=0; char c=getchar();
    13     x=0;
    14     while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
    15     if (c==EOF)exit(0);
    16     while(isdigit(c))x=x*10+c-'0',c=getchar();
    17     x=k?-x:x;
    18 }
    19 void read_char(char &c)
    20 {while(!isalpha(c=getchar())&&c!=EOF);}
    21 void init_ST()
    22 {
    23     for(int i=2;i<=max(n,m);i++)mm[i]=mm[i>>1]+1;
    24     for(int i=1;i<=n;i++)
    25         for(int j=1;j<=m;j++)
    26             mx[i][j][0][0]=dp[i][j];
    27     for(int k=1;k<=10;k++)
    28         for(int i=1;i<=n;i++)
    29             for(int j=1;j+(1<<k)-1<=m;j++)
    30                 mx[i][j][0][k]=max(mx[i][j][0][k-1],mx[i][j+(1<<(k-1))][0][k-1]);
    31     for(int k1=1;k1<=10;k1++)
    32         for(int k2=0;k2<=10;k2++)
    33             for(int i=1;i+(1<<k1)-1<=n;i++)
    34                 for(int j=1;j+(1<<k2)-1<=m;j++)
    35                     mx[i][j][k1][k2]=max(mx[i][j][k1-1][k2],mx[i+(1<<(k1-1))][j][k1-1][k2]);
    36 }
    37 int get_max(int x1,int y1,int x2,int y2)
    38 {
    39     int k1=mm[x2-x1+1],k2=mm[y2-y1+1];
    40     x2=x2-(1<<k1)+1;
    41     y2=y2-(1<<k2)+1;
    42     int a1=max(mx[x1][y1][k1][k2],mx[x1][y2][k1][k2]);
    43     int a2=max(mx[x2][y1][k1][k2],mx[x2][y2][k1][k2]);
    44     return max(a1,a2);
    45 }
    46 bool check(int mid)
    47 {
    48     return get_max(x1+mid-1,y1+mid-1,x2,y2)>=mid;     
    49 }
    50 int ef(int l,int r)
    51 {
    52     if (l==r)return l;
    53     int mid=(l+r+1)>>1;
    54     if (check(mid))return ef(mid,r);
    55     else return ef(l,mid-1);
    56 }
    57 int main()
    58 {
    59 #ifndef ONLINE_JUDGE
    60     freopen("aa.in","r",stdin);
    61 #endif
    62     read(n); read(m);
    63     for(int i=1;i<=n;i++)
    64         for(int j=1;j<=m;j++)
    65         {
    66             int x;
    67             read(x);
    68             if (x==0)continue;
    69             dp[i][j]=min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;
    70         }
    71     init_ST();
    72     int q;
    73     read(q);
    74     while(q--)
    75     {
    76         read(x1); read(y1); read(x2); read(y2);
    77         int ans=ef(0,min(x2-x1+1,y2-y1+1));
    78         printf("%d
    ",ans);
    79     }
    80 }
    View Code
  • 相关阅读:
    java Swing GUI 入门-简易货币计算器
    java Swing GUI 入门-简易加法器
    java Swing GUI 入门-文件读写器
    [转]Java图形化界面设计——布局管理器之BorderLayout
    WPF不让子窗口关闭的做法
    Tcp粘包处理+无脑处理
    HM NIS Edit + NSIS 打包客户端程序
    从0开始带你成为消息中间件实战高手(百度网盘)
    洛达1562A、1536u、杰里都有哪些区别?图片对比
    AB1562_UT软件分辨真假洛达1562A,洛达1562a怎么鉴别?
  • 原文地址:https://www.cnblogs.com/mmmqqdd/p/10836974.html
Copyright © 2011-2022 走看看