\(\mathcal{Description}\)

  Link.

  给一个 \(n\times n\) 的网格图,每个点是空格或障碍。\(q\) 次询问,每次给定两个坐标 \((r_1,c_1),(r_2,c_2)\),问最大的正方形边长 \(k\),满足 \(k\) 是奇数,且中心点在 \((r_1,c_1)\) 的正方形能够移动成为中心点在 \((r_2,c_2)\) 的正方形。

  \(n\le1000\),\(q\le3\times10^5\)。

\(\mathcal{Solution}\)

  这题咋黑了呢 owo?

  令障碍为 \(1\),空格为 \(0\),则一个正方形合法等价于子矩阵和为 \(0\),单次判断用前缀和做到 \(\mathcal O(1)\)。然后整体二分即可。

  复杂度 \(\mathcal O((n^2+q)\log n)\)。

\(\mathcal{Code}\)

#include <queue>
#include <cstdio>
#include <vector> typedef std::pair<int, int> pii; const int MAXN = 1000, MAXQ = 3e5;
const int MOVE[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
int n, q, sum[MAXN + 5][MAXN + 5];
int ans[MAXQ + 5], color[MAXN + 5][MAXN + 5];
std::vector<pii> arrived; struct Query { int r1, c1, r2, c2, id; };
std::vector<Query> qrys; inline int rint () {
int x = 0; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () );
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x;
} inline void wint ( const int x ) {
if ( 9 < x ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} inline bool legal ( const int r, const int c, const int rad ) {
int r1 = r - rad, c1 = c - rad, r2 = r + rad - 1, c2 = c + rad - 1;
return 0 <= r1 && 0 <= c1 && r2 <= n && c2 <= n
&& ! ( sum[r2][c2] - sum[r2][c1] - sum[r1][c2] + sum[r1][c1] );
} inline void paint ( const int sr, const int sc, const int rad, const int c ) {
static std::queue<pii> que;
que.push ( { sr, sc } ), color[sr][sc] = c;
arrived.push_back ( { sr, sc } );
while ( ! que.empty () ) {
pii p = que.front (); que.pop ();
for ( int w = 0, tx, ty; w < 4; ++ w ) {
tx = p.first + MOVE[w][0], ty = p.second + MOVE[w][1];
if ( ! color[tx][ty] && legal ( tx, ty, rad ) ) {
que.push ( { tx, ty } ), color[tx][ty] = c;
arrived.push_back ( { tx, ty } );
}
}
}
} inline void solve ( std::vector<Query>& curq, const int al, const int ar ) {
if ( curq.empty () ) return ;
if ( al == ar ) {
for ( auto q: curq ) ans[q.id] = al ? ( al << 1 ) - 1 : 0;
return ;
}
int amid = al + ar + 1 >> 1, col = 0;
for ( int i = amid, ei = n - amid + 1; i <= ei; ++ i ) {
for ( int j = amid, ej = n - amid + 1; j <= ej; ++ j ) {
if ( ! color[i][j] && legal ( i, j, amid ) ) {
paint ( i, j, amid, ++ col );
}
}
}
std::vector<Query> vecL, vecR;
for ( auto q: curq ) {
if ( color[q.r1][q.c1] && color[q.r1][q.c1] == color[q.r2][q.c2] ) vecR.push_back ( q );
else vecL.push_back ( q );
}
for ( pii c: arrived ) color[c.first][c.second] = 0;
arrived.clear ();
solve ( vecL, al, amid - 1 ), solve ( vecR, amid, ar );
} int main () {
n = rint ();
char tmp[MAXN + 5];
for ( int i = 1; i <= n; ++ i ) {
scanf ( "%s", tmp + 1 );
for ( int j = 1; j <= n; ++ j ) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + ( tmp[j] == '#' );
}
}
q = rint ();
for ( int i = 1, r1, c1, r2, c2; i <= q; ++ i ) {
r1 = rint (), c1 = rint (), r2 = rint (), c2 = rint ();
qrys.push_back ( { r1, c1, r2, c2, i } );
}
solve ( qrys, 0, n + 1 >> 1 );
for ( int i = 1; i <= q; ++ i ) wint ( ans[i] ), putchar ( '\n' );
return 0;
}

Solution -「CERC 2016」「洛谷 P3684」机棚障碍的更多相关文章

  1. 「区间DP」「洛谷P1043」数字游戏

    「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...

  2. Solution -「APIO 2016」「洛谷 P3643」划艇

    \(\mathcal{Description}\)   Link & 双倍经验.   给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...

  3. Solution -「JSOI 2019」「洛谷 P5334」节日庆典

    \(\mathscr{Description}\)   Link.   给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的).   \(|S|\le3\time ...

  4. Solution -「洛谷 P4372」Out of Sorts P

    \(\mathcal{Description}\)   OurOJ & 洛谷 P4372(几乎一致)   设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...

  5. Solution -「POI 2010」「洛谷 P3511」MOS-Bridges

    \(\mathcal{Description}\)   Link.(洛谷上这翻译真的一言难尽呐.   给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...

  6. 「洛谷4197」「BZOJ3545」peak【线段树合并】

    题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...

  7. 「洛谷3338」「ZJOI2014」力【FFT】

    题目链接 [BZOJ] [洛谷] 题解 首先我们需要对这个式子进行化简,否则对着这么大一坨东西只能暴力... \[F_i=\sum_{j<i} \frac{q_iq_j}{(i-j)^2}-\s ...

  8. 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】

    题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...

  9. 「洛谷3870」「TJOI2009」开关【线段树】

    题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...

随机推荐

  1. js获取设备公网ip + 服务器根据公网ip 获取IP信息

    1.前言 本来呢,想实现js定位功能,最少定位到城市,一开始,使用的是搜狐的api直接获取数据,可是,有时候搜狐不可靠,只能得到 公网ip,其他信息无用,就像这样 2.既然这样,还不如我自己请求自己的 ...

  2. 强化学习实战 | 自定义gym环境之显示字符串

    如果想用强化学习去实现扫雷.2048这种带有数字提示信息的游戏,自然是希望自定义 gym 环境时能把字符显示出来.上网查了很久,没有找到gym自带的图形工具Viewer可以显示字符串的信息,反而是通过 ...

  3. Spark案例练习-PV的统计

    关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新) 云盘目录说明: tools目录是安装包res   目录是每一个课件对应的代码和资源等doc  ...

  4. ASCII、Unicode和UTF-8等常见字符编码格式介绍

    信息存储在计算机中是转换成二进制来存储的,二进制的发明据说是来源于中国阴阳八卦.后德国数理哲学大师莱布尼茨是最早接触中华文化的欧洲人之一,从他的传教士朋友鲍威特寄给他的拉丁文译本<易经>中 ...

  5. 读《疯狂Java讲义》笔记总结二

    1.变量分类图 2.通过实例访问静态变量(类变量) 3.静态导入 4.构造器 5.创建对象内存过程

  6. HashMap和TreeMap的内部结构

    一.HashMap 1.基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hash ...

  7. 515. Find Largest Value in Each Tree Row

    You need to find the largest value in each row of a binary tree. Example: Input: 1 / \ 3 2 / \ \ 5 3 ...

  8. 华为联运游戏审核驳回:在未安装或需更新HMS Core的手机上,提示安装,点击取消后,游戏卡屏(集成的6.1.0.301版本游戏SDK)

    问题描述 更新游戏SDK到6.1.0.301版本之后,游戏包被审核驳回:在未安装或需更新华为移动服务版本(HMS Core)的手机上,提示安装华为移动服务(HMS Core),点击取消,游戏卡屏.修改 ...

  9. context包

    目录 Context包到底是干嘛用的? context原理 什么时候应该使用 Context? 如何创建 Context? 主协程通知有子协程,子协程又有多个子协程 context核心接口 empty ...

  10. ServletContext类介绍(对象的作用及演示、像map一样存取数据)

    什么是ServletContext类 1,什么是 ServletContext 1)ServletContext 是一个接口,它表示Servlet上下文对象 2)一个web工程,只有一个Servlet ...