【NOIP2016提高A组五校联考4】square
题目
分析
首先,设\(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的更多相关文章
- NOIP2016提高A组五校联考4总结
坑爹的第一题,我居然想了足足3个小时,而且还不确定是否正确. 于是,我就在这种情况下心惊胆跳的打了,好在ac了,否则就爆零了. 第二题,树形dp,本来差点就想到了正解,结果时间不够,没打完. 第三题, ...
- 【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} ...
- 【NOIP2016提高A组五校联考4】ksum
题目 分析 发现,当子段[l,r]被取了出来,那么[l-1,r].[l,r+1]一定也被取了出来. 那么,首先将[1,n]放入大顶堆,每次将堆顶的子段[l,r]取出来,因为它是堆顶,所以一定是最大的子 ...
- NOIP2016提高A组五校联考3总结
第一题,本来一开始就想到了数位dp,结果脑残地打了十几个转移方程,总是调试不出来,一气之下放弃了. 调第一题几乎调了整节比赛,第二第三都没它. 第二题连边找联通块. 第三题题解都打了三页,看都不想看. ...
- 【NOIP2016提高A组五校联考2】tree
题目 给一棵n 个结点的有根树,结点由1 到n 标号,根结点的标号为1.每个结点上有一个物品,第i 个结点上的物品价值为vi. 你需要从所有结点中选出若干个结点,使得对于任意一个被选中的结点,其到根的 ...
- 【NOIP2016提高A组五校联考2】running
题目 小胡同学是个热爱运动的好孩子. 每天晚上,小胡都会去操场上跑步,学校的操场可以看成一个由n个格子排成的一个环形,格子按照顺时针顺序从0 到n- 1 标号. 小胡观察到有m 个同学在跑步,最开始每 ...
- 【NOIP2016提高A组五校联考2】string
题目 给出一个长度为n, 由小写英文字母组成的字符串S, 求在所有由小写英文字母组成且长度为n 且恰好有k 位与S 不同的字符串中,给定字符串T 按照字典序排在第几位. 由于答案可能很大,模10^9 ...
- NOIP2016提高A组五校联考2总结
第一题用组合数各种乱搞,其恶心程度不一般.搞了很久才调对,比赛上出了一点bug,只拿了30分. 第二题我乱搞得出个错误的结论,本来自信满满60分,结果爆零了. 第三题,树形dp,在一开始的时候想到了, ...
- NOIP2016提高A组五校联考1总结
第一题二分,在比赛上明明想到的方法,结果考虑的时候似乎漏了什么,被否决掉了. 只打了个水法,10分. 第二题,最长不上升子序列,原题,类似的题目做过两道,直接搞定. 第三题,一开始想了一种通过在树上打 ...
随机推荐
- The window object
At the core of the BOM is the window object, which represents an instance of the browser. The window ...
- Flutter路由(一)
第一点:push使用 1.pushNamed——Navigator.of(context).pushNamed('routeName') Navigator.of(context).pushNamed ...
- Win32 编程 基础
Win32 程序开发的流程 message based, event driven Win32程序是message based, event driven.也就是说Win32程序的运行是依靠外部 ...
- Java中集合关键字的区别
1. ArrayList.Vector和Stack有什么区别? 1.ArrayList的方法和实现基本上和Vector一样,底层都是数组的实现(简:API基本一样) 2.Stack继承了Vec ...
- scrapy 正则汉字的提取方法
[\u4E00-\u9FA5]
- 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秒都 ...
- HDU 1159 Common Subsequence (动态规划、最长公共子序列)
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- SQL 生成表结构表数据脚本
数据库右击——>任务——>生成脚本——>选择表 ——>高级——>要编写脚本的数据的类型(架构和数据.仅限架构.仅限数据)
- redis内存满了怎么办?
redis最为缓存数据库,一般用于存储缓存数据,用于缓解数据库压力,但是缓存太多,内存满了怎么办呢.一般有以下几种方法 一.增加内存 redis存储于内存中,数据太多,占用太多内存,那么增加内存就是最 ...
- 洛谷 P1197 星球大战 题解
题面 并查集处理问题的基本思路:如果不是强制在线那么可以倒着处理,把删边改为可爱的加边,然后使用并查集来判断是否联通: 所以可以较为轻松的写出AC代码: #include <bits/stdc+ ...