JZOJ 4817. 【NOIP2016提高A组五校联考4】square

Introduction

给你一个 NM 的矩阵,给你T组询问,每组询问给定一个子矩阵,求一个最大的正方形的边长,使这个正方形内的所有元素都为 1 且这个正方形在子矩阵内.
数据范围
N,M<=1000,T<=1000000

Solution

这道题很显然是DP。
Fi,j 表示以(i,j)为右下角,符合题意的最大边长。
那么转移方程为

Fi,j=max(Fi1,j,Fi,j1,Fi1,j1)Ai,j=1

可是这样远远不能AC.
这个时候我们想到了RMQ算法(二维的)。
我们设 rmqi,j,k,l 为当前以 (k2i+1,l2j+1) 为右下角, (k,l) 为右下角的正方形符合题意的最大边长。
rmqi,j,k,l 由之前的3个小矩阵更新。
所以转移方程为
rmqi,j,k,l=max(rmqi1,j,k2i,l,rmqi,j1,k,l2j,rmqi1,j1,k2i,l2j)

特殊情况:
①i=0,那么 rmqi,j,k,l=max(rmqi,j1,k,l2j)
②j=0,那么 rmqi,j,k,l=max(rmqi1,j,k2i,l)
询问
对于询问,我们只需要去求4个矩阵的最大值就好了^_^
m1=log2(x2x1+1)m2=log2(y2y1+1)
ans=max(rmq[m1][m2][x2][y2],rmq[m1][m2][x1+2m11][y1+2m21]),rmq[m1][m2][x2][y1+2m21],rmq[m1][m2][x1+2m11][y2]))

然后ans≥mid就合法,否则不合法。

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define N 1003
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
int _2[11],rmq[10][10][N][N];
int i,j,k,l,r,mid,q,n,m,temp,X1,Y1,X2,Y2,ans;
inline int read()
{
    int data=0;
    char ch=0;
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
    return data;
}
bool ok(int X1,int Y1,int X2,int Y2,int mid)
{
    int lx=log2(X2-X1+1),ly=log2(Y2-Y1+1);
    ans=max(max(rmq[lx][ly][X2][Y2],rmq[lx][ly][X1+_2[lx]-1][Y1+_2[ly]-1]),
            max(rmq[lx][ly][X2][Y1+_2[ly]-1],rmq[lx][ly][X1+_2[lx]-1][Y2]));
    if (ans>=mid) return 1;return 0;
}
int main()
{
    _2[0]=1;fo(i,1,10) _2[i]=_2[i-1]*2;
    n=read();m=read();
    fo(i,1,n)
        fo(j,1,m) rmq[0][0][i][j]=read();
    fo(i,2,n)
        fo(j,2,m)
            if (rmq[0][0][i][j])
                rmq[0][0][i][j]=min(min(rmq[0][0][i-1][j],rmq[0][0][i][j-1]),rmq[0][0][i-1][j-1])+1;
    fo(i,0,log2(n))
        fo(j,0,log2(m))
            if (!i && !j) continue;
            else fo(k,_2[i],n)
                     fo(l,_2[j],m)
                     {
                         if (!i) rmq[i][j][k][l]=max(rmq[i][j-1][k][l],rmq[i][j-1][k][l-_2[j-1]]);else
                         if (!j) rmq[i][j][k][l]=max(rmq[i-1][j][k][l],rmq[i-1][j][k-_2[i-1]][l]);else
                         rmq[i][j][k][l]=max(max(rmq[i-1][j][k][l],rmq[i-1][j][k-_2[i-1]][l]),
                                             max(rmq[i][j-1][k][l],rmq[i][j-1][k][l-_2[j-1]]));
                     }
    q=read();
    fo(i,1,q)
    {
        X1=read(),Y1=read(),X2=read(),Y2=read();
        l=0;r=min(X2-X1+1,Y2-Y1+1);
        while (l<r)
        {
            if (l==r-1)
            {
                if (ok(X1+r-1,Y1+r-1,X2,Y2,r)) l=r;
                break;
            }
            mid=(l+r)/2;
            if (ok(X1+mid-1,Y1+mid-1,X2,Y2,mid)) l=mid;else r=mid-1;
        }
        printf("%d\n",l);
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的校园二手书交易平台,源码+数据库+毕业论文+视频演示 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的校园二手书交易平台实现了图书信息查询。系统用到了关系型数据库中MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让校园二手书交易平台更能从理念走到现实,确确实实的让人们提升信息处理效率。 关键字:信息管理,时效性,安全性,MySql;Spring Boot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值