\(\text{Solution}\)

这个问题是不好判断的

考虑简单点的,\((1,1)\) 到 \((h,w)\) 是否连通

那么只要在最外围一圈 #(显然一些位置不能加),判断 \((h+1,n)\) 和 \((0,w+1)\) 是否能通过 # 八连通即可

如果是双连通呢?只要这两点所在连通块不能通过只加一个 # 就连通

看起来很不可做的题猜测一些简单结论就很可做了

判断否就考虑加一个 # 就连通的位置,这个 # 必然是连接了两个连通块

考虑这两个连通块的类别,一是新填的两个 #,O(k^2) 枚举即可

二是连接了原图中的两个连通块,这两个连通块又通过新的 # 连通了 \((h+1,n)\) 或 \((0,w+1)\)

于是把所有这样的连通块记录下来,判断两两是否在原图中只加一个 # 就连通

三是一个新 # 和原图中的连通块,发现处理可以和二一样

判断两连通块是否只加一个 # 就连通可以用哈希表预处理

一次询问是临时的,可撤销并查集即可

\(\text{Code}\)

#include <bits/stdc++.h>
#define IN inline
#define eb emplace_back
using namespace std; int n, m, q, id[1005][1005];
char str[1005], mp[1005][1005]; const int N = 1e6 + 5e3;
struct DSU {
int fa[N], sz[N], top;
struct Edge{int u, v;}stk[N];
IN int find(int x){while (fa[x] != x) x = fa[x]; return x;}
IN void merge(int x, int y) {
int u = find(x), v = find(y);
if (u == v) return; if (sz[u] > sz[v]) swap(u, v);
fa[u] = v, sz[v] += sz[u], stk[++top] = Edge{u, v};
}
IN void clear(int lst) {
for(int u, v; top != lst; --top)
u = stk[top].u, v = stk[top].v, sz[v] -= sz[u], fa[u] = u;
}
}T1, T2; int fx[9][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}};
unordered_map<int, int> hs[N]; void dfs(int x, int y, int d, int p) {
if ((x == 2 && y == 2) || (x == n - 1 && y == m - 1)) return;
if (mp[x][y] == '#') hs[p][T1.find(id[x][y])] = 1;
if (!d) return;
for(int k = 0; k < 8; k++) {
int xx = x + fx[k][0], yy = y + fx[k][1];
if (id[xx][yy]) dfs(xx, yy, d - 1, p);
}
} void Init() {
scanf("%d%d%d", &n, &m, &q), n += 2, m += 2;
for(int i = 2; i < n; i++) scanf("%s", mp[i] + 2);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) id[i][j] = (i - 1) * m + j;
for(int j = 1; j <= m; j++) mp[1][j] = mp[n][j] = '#';
for(int i = 1; i <= n; i++) mp[i][1] = mp[i][m] = '#';
mp[1][1] = mp[1][2] = mp[2][1] = mp[n - 1][m] = mp[n][m - 1] = mp[n][m] = '.';
for(int i = 1; i <= n * m; i++) T1.fa[i] = i, T1.sz[i] = 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) if (mp[i][j] == '#')
for(int k = 0; k < 8; k++) {
int x = i + fx[k][0], y = j + fx[k][1];
if (id[x][y] && mp[x][y] == '#') T1.merge(id[i][j], id[x][y]);
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) dfs(i, j, 2, T1.find(id[i][j]));
for(int i = 1; i <= n * m; i++) T2.fa[i] = T1.fa[i], T2.sz[i] = T1.sz[i];
} int X[15], Y[15]; int main() {
Init();
for(; q; --q) {
int K; scanf("%d", &K);
for(int i = 1; i <= K; i++) scanf("%d%d", &X[i], &Y[i]), mp[++X[i]][++Y[i]] = '#';
int lst = T2.top;
for(int i = 1; i <= K; i++)
for(int k = 0; k < 8; k++) {
int x = X[i] + fx[k][0], y = Y[i] + fx[k][1];
if (id[x][y] && mp[x][y] == '#') T2.merge(id[X[i]][Y[i]], id[x][y]);
}
int flag = 0;
for(int i = 1; i <= K && !flag; i++)
for(int j = 1; j <= K; j++) if (max(abs(X[i] - X[j]), abs(Y[i] - Y[j])) <= 2) {
if (T2.find(id[X[i]][Y[i]]) == T2.find(id[1][m]) && T2.find(id[X[j]][Y[j]]) == T2.find(id[n][1])) {
flag = 1; break;
}
}
vector<int> Vr, Vl; Vr.eb(T1.find(id[1][m])), Vl.eb(T1.find(id[n][1]));
for(int i = 1; i <= K; i++) {
for(int k = 0; k <= 8; k++) {
int x = X[i] + fx[k][0], y = Y[i] + fx[k][1];
if (id[x][y] && T2.find(id[x][y]) == T2.find(id[1][m])) Vr.eb(T1.find(id[x][y]));
if (id[x][y] && T2.find(id[x][y]) == T2.find(id[n][1])) Vl.eb(T1.find(id[x][y]));
}
}
for(auto kr : Vr) for(auto kl : Vl)
if (hs[kr].find(kl) != hs[kr].end() || hs[kl].find(kr) != hs[kl].end()){flag = 1; break;}
if (!flag) puts("YES"); else puts("NO"); fflush(stdout);
T2.clear(lst); for(int i = 1; i <= K; i++) mp[X[i]][Y[i]] = '.';
}
}

CF750H New Year and Snowy Grid的更多相关文章

  1. ZJOI2018游记Round1

    广告 ZJOI2018Round2游记 All Falls Down 非常感谢学弟学妹们捧场游记虽然这是一篇假游记 ZJOI Round1今天正式落下帷幕.在这过去的三天里遇到了很多朋友,见识了很多有 ...

  2. ExtJS 4.2 Grid组件的单元格合并

    ExtJS 4.2 Grid组件本身并没有提供单元格合并功能,需要自己实现这个功能. 目录 1. 原理 2. 多列合并 3. 代码与在线演示 1. 原理 1.1 HTML代码分析 首先创建一个Grid ...

  3. WPF中Grid实现网格,表格样式通用类

    /// <summary> /// 给Grid添加边框线 /// </summary> /// <param name="grid"></ ...

  4. 在 Windows Phone 中,为 Grid 添加 Tilt 效果

    在 Windows Phone 中,Tilt 效果是比较经典的效果,我们可以很简单的为按钮等控件添加这样的效果(使用 Windows Phone Toolkit 的Tilt 效果),但是,如果我们想要 ...

  5. wpf 列表、菜单 收起与展开,通过Grid DoubleAnimation或者Expander实现

    菜单收缩有很多种方法具体如何实现还是看个人想法: 第一种通过后台控制收起与展开: 效果图: 代码 : <Grid> <Grid.ColumnDefinitions> <C ...

  6. Sencha ExtJS 6 Widget Grid 入门

    最近由于业务需要,研究了一下Sencha ExtJS 6 ,虽然UI和性能上据相关资料说都有提升,但是用起来确实不太顺手,而且用Sencha cmd工具进行测试和发布,很多内部细节都是隐藏的,出了问题 ...

  7. WPF CheckBox样式 ScrollViewer样式 WrapPanel、StackPanel、Grid布局

    本节讲述布局,顺带加点样式给大家看看~单纯学布局,肯定是枯燥的~哈哈 那如上界面,该如何设计呢? 1.一些布局元素经常用到.Grid StackPanel Canvas WrapPanel等.如上这种 ...

  8. [转]ExtJS Grid 分页时保持选中的简单实现方法

    原文地址 :http://www.qeefee.com/article/ext-grid-keep-paging-selection ExtJS中经常要用到分页和选择,但是当选择遇到分页的时候,杯具就 ...

  9. [转]extjs grid的Ext.grid.CheckboxSelectionModel默认选中解决方法

    原文地址:http://379548695.iteye.com/blog/1167234 grid的复选框定义如下:   var sm = new Ext.grid.CheckboxSelection ...

  10. EXTJS中grid的数据特殊显示,不同窗口的数据传递

    //EXTJS中grid的数据特殊显示renderer : function(value, metaData, record, rowIndex, colIndex, store, view) { v ...

随机推荐

  1. ElasticSearch7.6.1学习笔记-狂神

    ElasticSearch:7.6.1 https://gitee.com/yujie.louis/elastic-search 笔记,代码,安装包等 什么是ElasticSearch? Elasti ...

  2. webflux延迟队列逻辑更改过程记录

    title : webflux延迟队列逻辑更改过程记录 author : simonLee date : 2022/11/22 10:26 目录 webflux延迟队列逻辑更改过程记录 一.问题背景 ...

  3. 互斥锁 线程理论 GIL全局解释器锁 死锁现象 信号量 event事件 进程池与线程池 协程实现并发

    目录 互斥锁 multiprocessing Lock类 锁的种类 线程理论 进程和线程对比 开线程的两种方式(类似进程) 方式1 使用Thread()创建线程对象 方式2 重写Thread类run方 ...

  4. Go DevOps大厂运维平台开发进阶实战营

    使用 Jenkinsfile 创建流水线已报名老男孩运维课,见底下评论.enkinsfile 是一个文本文件,它包含 Jenkins 流水线的定义,并被检入源代码控制仓库.Jenkinsfile 将整 ...

  5. 搭建IIS网站后,点击浏览地址,报403错误

    点击左侧的浏览地址,报右侧的错误,可将目录浏览进行启用 双击进去,进行启用即可

  6. maven 项目依赖自动导入失败(pom.xml 文件爆红),解决--手动导入

    idea 报错信息提示:Dependency 'xxx' not found 解决方法:可以通过更换仓库的镜像配置解决,但是一般咱都在配置maven的时候,设置成阿里云仓库镜像了,更换成其他的,可能出 ...

  7. 绿色版MySQL8.0.26安装流程

    下载  5.7 8.0 官网 https://dev.mysql.com/downloads/mysql/ 国内镜像网站 https://developer.aliyun.com/mirror/ ​  ...

  8. 何为GUI???

    1.GUI是什么–简介 GUI的全称为Graphical User Interface,图形化界面或图形用户接口,是指采用图形方式显示的计算机操作环境用户接口.与早期计算机使用的命令行界面相比,图形界 ...

  9. 学习ASP.NET Core Blazor编程系列十九——文件上传(下)

    学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...

  10. Spark详解(02) - Spark概述

    Spark详解(02) - Spark概述 什么是Spark Hadoop主要解决,海量数据的存储和海量数据的分析计算. Spark是一种基于内存的快速.通用.可扩展的大数据分析计算引擎. Hadoo ...