题目

分析

首先,设\(f_{i,j}\)表示最大的以(i,j)为左下角的正方形的边长。

转移显然,\(f_{i,j}=\max(f_{i-1,j},f_{i,j-1},f_{i-1,j-1})+1\)

接着,再设\(g_{i,j,k,l}\)表示在以\((k,l)\)为左上角,\((k+2^i-1,l+2^j-1)\)为右下角的矩阵中,最大的f。

二维rmq就不讲了。

假设询问矩阵(x,y,x1,y1),

二分答案ans(想想为什么?)



用rmq看红色区域中的最大f值是否合法。

注意:出题人将输入调的太大了,要打读入优化。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=1002;
using namespace std;
int f[N][N],n,m,T,g[11][11][N][N],a[N][N],logn,logm;
int read(int &n)
{
char ch=' ';
int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-') w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar()) q=q*10+ch-48;n=q*w;
return n;
}
int min2(int x,int y)
{
if(x>y) x=y;
return x;
}
int max2(int x,int y)
{
if(x<y) x=y;
return x;
}
int min1(int x,int y,int z)
{
if(x>y) x=y;
if(x>z) x=z;
return x;
}
int max1(int x,int y,int z,int a)
{
if(x<y) x=y;
if(x<z) x=z;
if(x<a) x=a;
return x;
}
int pref()
{
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(a[i][j])
g[0][0][i][j]=f[i][j]=min1(f[i-1][j-1],f[i-1][j],f[i][j-1])+1;
}
int prermq()
{
int i,j,k,l;
for(i=0;i<=logn;i++)
{ for(j=0;j<=logm;j++)
{
if(j+i!=0)
{
int p=1<<(i-1);
int q=1<<(j-1);
for(k=1;k<=n;k++)
if(k+p<=n)
{
for(l=1;l<=m;l++)
if(l+q<=m)
{
if(i!=0 && j!=0)
g[i][j][k][l]=max1(g[i-1][j-1][k][l],g[i-1][j-1][k+p][l],g[i-1][j-1][k+p][l+q],g[i-1][j-1][k][l+q]);
else
if(i==0)
g[i][j][k][l]=max2(g[i][j-1][k][l],g[i][j-1][k][l+q]);
else
if(j==0)
g[i][j][k][l]=max2(g[i-1][j][k][l],g[i-1][j][k+p][l]);
}
else break;
}
else break;
}
}
}
}
int rmq(int x,int y,int x1,int y1)
{
int p=log2(x1-x+1),q=log2(y1-y+1);
return max1(g[p][q][x][y],g[p][q][x1-(1<<p)+1][y],g[p][q][x][y1-(1<<q)+1],g[p][q][x1-(1<<p)+1][y1-(1<<q)+1]);
}
int rf(int x,int y,int x1,int y1)
{
int lx=x1-x+1,ly=y1-y+1,l=1,r=min2(lx,ly);
while(l<r-1)
{
int mid=(l+r)/2;
if(rmq(x+mid-1,y+mid-1,x1,y1)>=mid)
l=mid;
else
r=mid-1;
}
if(rmq(x+r-1,y+r-1,x1,y1)>=r)
printf("%d\n",r);
else
if(rmq(x+l-1,y+l-1,x1,y1)>=l)
printf("%d\n",l);
else
printf("0\n");
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
read(a[i][j]);
f[i][j]=a[i][j];
}
pref();
logn=log2(n);
logm=log2(m);
prermq();
scanf("%d",&T);
int x1,x2,y1,y2;
for(int i=1;i<=T;i++)
{
read(x1);
read(y1);
read(x2);
read(y2);
rf(x1,y1,x2,y2);
}
}

【NOIP2016提高A组五校联考4】square的更多相关文章

  1. NOIP2016提高A组五校联考4总结

    坑爹的第一题,我居然想了足足3个小时,而且还不确定是否正确. 于是,我就在这种情况下心惊胆跳的打了,好在ac了,否则就爆零了. 第二题,树形dp,本来差点就想到了正解,结果时间不够,没打完. 第三题, ...

  2. 【NOIP2016提高A组五校联考4】label

    题目 题目 20%算法 设\(f_{i,j}\)表示第i个节点选了j这个权值的方案数. 显然转移方程为,\[f_{i,j}=\Pi_{v=son(i)}(\sum_{k=1}^{j-k}f_{v,k} ...

  3. 【NOIP2016提高A组五校联考4】ksum

    题目 分析 发现,当子段[l,r]被取了出来,那么[l-1,r].[l,r+1]一定也被取了出来. 那么,首先将[1,n]放入大顶堆,每次将堆顶的子段[l,r]取出来,因为它是堆顶,所以一定是最大的子 ...

  4. NOIP2016提高A组五校联考3总结

    第一题,本来一开始就想到了数位dp,结果脑残地打了十几个转移方程,总是调试不出来,一气之下放弃了. 调第一题几乎调了整节比赛,第二第三都没它. 第二题连边找联通块. 第三题题解都打了三页,看都不想看. ...

  5. 【NOIP2016提高A组五校联考2】tree

    题目 给一棵n 个结点的有根树,结点由1 到n 标号,根结点的标号为1.每个结点上有一个物品,第i 个结点上的物品价值为vi. 你需要从所有结点中选出若干个结点,使得对于任意一个被选中的结点,其到根的 ...

  6. 【NOIP2016提高A组五校联考2】running

    题目 小胡同学是个热爱运动的好孩子. 每天晚上,小胡都会去操场上跑步,学校的操场可以看成一个由n个格子排成的一个环形,格子按照顺时针顺序从0 到n- 1 标号. 小胡观察到有m 个同学在跑步,最开始每 ...

  7. 【NOIP2016提高A组五校联考2】string

    题目 给出一个长度为n, 由小写英文字母组成的字符串S, 求在所有由小写英文字母组成且长度为n 且恰好有k 位与S 不同的字符串中,给定字符串T 按照字典序排在第几位. 由于答案可能很大,模10^9 ...

  8. NOIP2016提高A组五校联考2总结

    第一题用组合数各种乱搞,其恶心程度不一般.搞了很久才调对,比赛上出了一点bug,只拿了30分. 第二题我乱搞得出个错误的结论,本来自信满满60分,结果爆零了. 第三题,树形dp,在一开始的时候想到了, ...

  9. NOIP2016提高A组五校联考1总结

    第一题二分,在比赛上明明想到的方法,结果考虑的时候似乎漏了什么,被否决掉了. 只打了个水法,10分. 第二题,最长不上升子序列,原题,类似的题目做过两道,直接搞定. 第三题,一开始想了一种通过在树上打 ...

随机推荐

  1. The window object

    At the core of the BOM is the window object, which represents an instance of the browser. The window ...

  2. Flutter路由(一)

    第一点:push使用 1.pushNamed——Navigator.of(context).pushNamed('routeName') Navigator.of(context).pushNamed ...

  3. Win32 编程 基础

    Win32    程序开发的流程 message based, event driven Win32程序是message based, event driven.也就是说Win32程序的运行是依靠外部 ...

  4. Java中集合关键字的区别

    1. ArrayList.Vector和Stack有什么区别? 1.ArrayList的方法和实现基本上和Vector一样,底层都是数组的实现(简:API基本一样) ​   2.Stack继承了Vec ...

  5. scrapy 正则汉字的提取方法

    [\u4E00-\u9FA5]

  6. CF498B Name That Tune(动态规划dp)

    CF498B 动态规划f[i][j]表示前i秒时间听了j首歌的概率,则有: \(f[i][j]=∑f[i-k][j-1]*(1-p_j)^{k-1}*p_j\) k枚举i秒前的每一秒,要求前i-1秒都 ...

  7. HDU 1159 Common Subsequence (动态规划、最长公共子序列)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  8. SQL 生成表结构表数据脚本

    数据库右击——>任务——>生成脚本——>选择表 ——>高级——>要编写脚本的数据的类型(架构和数据.仅限架构.仅限数据)

  9. redis内存满了怎么办?

    redis最为缓存数据库,一般用于存储缓存数据,用于缓解数据库压力,但是缓存太多,内存满了怎么办呢.一般有以下几种方法 一.增加内存 redis存储于内存中,数据太多,占用太多内存,那么增加内存就是最 ...

  10. 洛谷 P1197 星球大战 题解

    题面 并查集处理问题的基本思路:如果不是强制在线那么可以倒着处理,把删边改为可爱的加边,然后使用并查集来判断是否联通: 所以可以较为轻松的写出AC代码: #include <bits/stdc+ ...