题:https://codeforces.com/contest/1301/problem/E

题意:给个n*m的图形,q个询问,每次询问问询问区间最大的合法logo的面积是多少

分析:由于logo是由4个同色的小正方形组成的,所以我们先考虑一个数组val[i][j]表示[i][j]位置为‘R' , [i+1][j]位置为’Y‘,[i][j+1]位置为’G‘,[i+1][j+1]位置为’B'所能形成的最大图案边长是多少;

   因为这样就只要预处理‘R’正方形沿着左上能形成的最大正方形,“Y”沿着左下能形成的最大正方形,’G‘沿着右上能形成的最大正方形,”B“沿着右下能形成的最大正方形,然后对于位置[i][j]就取min这四者;

   对于询问,我们只要二分答案搜到最大符合条件的就行了,注意这里的二分的mid,假设询问[r1,c1,r2,c2],则搜索访问应该在[r1+mid-1,c1+mid-1,r2-mid,c2-mid]的范围内搜索才是合法的;

   因为我们在二分时要求满足条件的mid就行,所以这里对val进行倍增处理;

   合法性:因为小的合法图案一定在大的合法图案里面,所以对val取的图案也许是超过询问范围,但我们上面已经对询问范围进行如上缩减,所以是合法的

#include<bits/stdc++.h>
using namespace std;
const int M=;
const int N=;
int ex[][M][M];
int n,m,q;
int val[M][M],f[N][N][M][M],lg[M];
char s[M][M];
void RMQ(int n,int m){
for(int i=;i<n;i++)
for(int j=;j<m;j++)
f[][][i+][j+]=val[i][j];
for(int i=;i<M;i++)
lg[i]=+lg[i/];
for(int i=;i<=n;i++)
for(int k2=;(<<k2)<=m;k2++)
for(int j=;j<=m-(<<k2)+;j++)
f[][k2][i][j]=max(f[][k2-][i][j],f[][k2-][i][j+(<<(k2-))]);
for(int k1=;(<<k1)<=n;k1++)
for(int i=;i<=n-(<<k1)+;i++)
for(int k2=;(<<k2)<=m;k2++)
for(int j=;j<=m-(<<k2)+;j++)
f[k1][k2][i][j]=max(f[k1-][k2][i][j],f[k1-][k2][i+(<<(k1-))][j]);
} int query(int x1,int y1,int x2,int y2){
int k1=lg[x2-x1+];
int k2=lg[y2-y1+];
x2=x2-(<<k1)+;
y2=y2-(<<k2)+;
return max(f[k1][k2][x1][y1],max(f[k1][k2][x1][y2],max(f[k1][k2][x2][y1],f[k1][k2][x2][y2])));
}
bool check(int r1,int c1,int r2,int c2,int midd){
r1=r1+midd-;
c1=c1+midd-;
r2=r2-midd;
c2=c2-midd;
if(r1>r2||c1>c2)
return false;
return query(r1,c1,r2,c2)>=midd;
}
void color(int fx,int fy,char c,int k){///根据进来的参数不同,组成不同方向相同颜色的最大正方形
int stx=,sty=;
if(fx==-)stx=n-;
if(fy==-)sty=m-;
///while遍历二维数组
while(stx<n&&stx>=){
while(sty<m&&sty>=){
if(s[stx][sty]==c){
ex[k][stx][sty]=;
if(stx-fx>=&&stx-fx<n&&sty-fy>=&&sty-fy<m){///正方形区域取最小值
if(s[stx-fx][sty]==c&&s[stx][sty-fy]==c&&s[stx-fx][sty-fy]==c){
ex[k][stx][sty]=min(ex[k][stx-fx][sty],
min(ex[k][stx][sty-fy],ex[k][stx-fx][sty-fy]))+;
}
}
}
sty+=fy;
}
sty=;if(fy==-)sty=m-;
stx+=fx;
}
}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<n;i++)
scanf("%s",s[i]);
//
color(,,'R',);
color(-,,'Y',);
color(,-,'G',);
color(-,-,'B',);
for(int i=;i<n-;i++){
for(int j=;j<m-;j++){
if(s[i][j]=='R'&&s[i+][j]=='Y'&&s[i][j+]=='G'&&s[i+][j+]=='B'){
val[i][j]=min(ex[][i][j],min(ex[][i+][j],min(ex[][i][j+],ex[][i+][j+])));
}
}
}
//
RMQ(n,m); //
for(int i=;i<q;i++){
int r1,c1,r2,c2,ans=;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
int l=,r=min(r2-r1,c2-c1);
while(l<=r){
int midd=(l+r)>>;
if(check(r1,c1,r2,c2,midd)){
ans=midd;
l=midd+;
}
else
r=midd-;
}
printf("%d\n",*ans*ans);
}
return ;
}

Codeforces Round #619 (Div. 2)E思维+二维RMQ的更多相关文章

  1. Codeforces Round #368 (Div. 2) E. Garlands 二维树状数组 暴力

    E. Garlands 题目连接: http://www.codeforces.com/contest/707/problem/E Description Like all children, Ale ...

  2. Codeforces Round #619 (Div. 2)

    A. Three Strings 题意:给三个长度相同的非空字符串abc,依次将c中的每个字符和a或者b中对应位置的字符进行交换,交换必须进行,问能否使得ab相同. 思路:对于每一个位置,如果三个字符 ...

  3. codeforces 713D D. Animals and Puzzle 二分+二维rmq

    题目链接 给一个01矩阵, 然后每个询问给出两个坐标(x1, y1), (x2, y2). 问你这个范围内的最大全1正方形的边长是多少. 我们dp算出以i, j为右下角的正方形边长最大值. 然后用二维 ...

  4. 【CF1256】Codeforces Round #598 (Div. 3) 【思维+贪心+DP】

    https://codeforces.com/contest/1256 A:Payment Without Change[思维] 题意:给你a个价值n的物品和b个价值1的物品,问是否存在取物方案使得价 ...

  5. Codeforces Round #143 (Div. 2) (ABCD 思维场)

    题目连链接:http://codeforces.com/contest/231 A. Team time limit per test:2 seconds memory limit per test: ...

  6. Codeforces Round #395 (Div. 2)(A.思维,B,水)

    A. Taymyr is calling you time limit per test:1 second memory limit per test:256 megabytes input:stan ...

  7. Codeforces Round #416 (Div. 2)(A,思维题,暴力,B,思维题,暴力)

    A. Vladik and Courtesy time limit per test:2 seconds memory limit per test:256 megabytes input:stand ...

  8. Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS

    题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...

  9. Codeforces Round #539 (Div. 2) D 思维

    https://codeforces.com/contest/1113/problem/D 题意 将一个回文串切成一段一段,重新拼接,组成一个新的回文串,问最少切几刀 题解 首先无论奇偶串,最多只会切 ...

随机推荐

  1. Python中pandas透视表pivot_table功能详解(非常简单易懂)

    一文看懂pandas的透视表pivot_table 一.概述 1.1 什么是透视表? 透视表是一种可以对数据动态排布并且分类汇总的表格格式.或许大多数人都在Excel使用过数据透视表,也体会到它的强大 ...

  2. Golang的运算符-算数运算符

    Golang的运算符-算数运算符 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.算术运算符概述 常见的算术运算符: +: 可表示正号,如",结果为"Jaso ...

  3. 洛谷 三月月赛 A

    模拟模拟 #include<bits/stdc++.h> using namespace std; inline int ra() { ,f=; char ch=getchar(); ; ...

  4. cf 543 D. Road Improvement

    (懒得想了,,又是DP) #include<bits/stdc++.h> #define N 200005 #define LL long long #define inf 0x3f3f3 ...

  5. 09.swoole学习笔记--创建进程

    <?php //进程数组 $workers=[]; //创建进程的数据量 $worker_num=; //创建启动进程 ;$i<$worker_num;$i++){ //创建单独新进程 $ ...

  6. Spring课程 Spring入门篇 7-3 advice扩展

    课程链接: 1 解析 1.1 advice中aspect 切面传参 1.2 通知参数名称——argNames属性, 参数为 JoinPoint.ProceedingJoinPoint.JoinPoin ...

  7. pyinstaller打包PySide2写的GUI程序,调用ffmpeg隐藏CMD控制台解决方案

    1 问题描述 使用PySide2写了一个GUI程序,调用ffmpeg命令行工具,做简单的批量视频处理(调整帧宽度.帧高度.视频变速.降低视频码率达到限制视频大小),使用了ffmpeg. ffmpeg- ...

  8. 095-PHP遍历关联数组,并修改数组元素值

    <?php $arr=array('I'=>1,'II'=>2,'III'=>3,'IV'=>4,'V'=>5); //定义一个数组 echo '修改之前数组信息: ...

  9. opencv python训练人脸识别

    总计分为三个步骤 一.捕获人脸照片 二.对捕获的照片进行训练 三.加载训练的数据,识别 使用python3.6.8,opencv,numpy,pil 第一步:通过笔记本前置摄像头捕获脸部图片 将捕获的 ...

  10. c# 占位符 {0} {1}

    占位符就是先占住一个固定的位置,等着你再往里面添加内容的符号.站位符由{数字}组成,数字由0开始编号. 第1个占位符:{0} 第2个占位符:{1} 第2个占位符:{2} 初学C#之变量.占位符.转义符 ...