CodeforcesRound#749(Div.1+Div.2,basedonTechnocup2022EliminationRound1)-C. Omkar and Determination-题解
Posted Tisfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeforcesRound#749(Div.1+Div.2,basedonTechnocup2022EliminationRound1)-C. Omkar and Determination-题解相关的知识,希望对你有一定的参考价值。
在这里插入代码片
目录
Codeforces Round #749 (Div. 1 + Div. 2, based on Technocup 2022 Elimination Round 1) - C. Omkar and Determination
传送门
Time Limit: 2 seconds
Memory Limit: 256 megabytes
Problem Description
The problem statement looms below, filling you with determination.
Consider a grid in which some cells are empty and some cells are filled. Call a cell in this grid exitable if, starting at that cell, you can exit the grid by moving up and left through only empty cells. This includes the cell itself, so all filled in cells are not exitable. Note that you can exit the grid from any leftmost empty cell (cell in the first column) by going left, and from any topmost empty cell (cell in the first row) by going up.
Let’s call a grid determinable if, given only which cells are exitable, we can exactly determine which cells are filled in and which aren’t.
You are given a grid a of dimensions n × m n×m n×m , i. e. a grid with n n n rows and m m m columns. You need to answer q q q queries ( 1 ≤ q ≤ 2 ⋅ 1 0 5 ) (1≤q≤2⋅10^5) (1≤q≤2⋅105). Each query gives two integers x 1 , x 2 ( 1 ≤ x 1 ≤ x 2 ≤ m ) x_1,x_2 (1≤x_1≤x_2≤m) x1,x2(1≤x1≤x2≤m) and asks whether the subgrid of a consisting of the columns x 1 , x 1 + 1 , … , x 2 − 1 , x 2 x_1,x_1+1,…,x_2−1,x_2 x1,x1+1,…,x2−1,x2 is determinable.
Input
The first line contains two integers n , m ( 1 ≤ n , m ≤ 1 0 6 , n m ≤ 1 0 6 ) n,m (1≤n,m≤10^6, nm≤10^6) n,m(1≤n,m≤106,nm≤106) — the dimensions of the grid a.
n n n lines follow. The y y y-th line contains m characters, the x x x-th of which is ‘X’ if the cell on the intersection of the the y y y-th row and x x x-th column is filled and “.” if it is empty.
The next line contains a single integer q ( 1 ≤ q ≤ 2 ⋅ 1 0 5 ) q (1≤q≤2⋅10^5) q(1≤q≤2⋅105) — the number of queries.
q q q lines follow. Each line contains two integers x 1 x_1 x1 and x 2 ( 1 ≤ x 1 ≤ x 2 ≤ m ) x_2 (1≤x_1≤x_2≤m) x2(1≤x1≤x2≤m), representing a query asking whether the subgrid of a containing the columns x 1 , x 1 + 1 , … , x 2 − 1 , x 2 x_1,x_1+1,…,x_2−1,x_2 x1,x1+1,…,x2−1,x2 is determinable.
Output
For each query, output one line containing “YES” if the subgrid specified by the query is determinable and “NO” otherwise. The output is case insensitive (so “yEs” and “No” will also be accepted).
Sample Input
4 5
..XXX
...X.
...X.
...X.
5
1 3
3 3
4 5
5 5
1 5
Sample Onput
YES
YES
NO
YES
NO
Note
For each query of the example, the corresponding subgrid is displayed twice below: first in its input format, then with each cell marked as “E” if it is exitable and “N” otherwise.
For the first query:
..X EEN
... EEE
... EEE
... EEE
For the second query:
X N
. E
. E
. E
Note that you can exit the grid by going left from any leftmost cell (or up from any topmost cell); you do not need to reach the top left corner cell to exit the grid.
For the third query:
XX NN
X. NN
X. NN
X. NN
This subgrid cannot be determined only from whether each cell is exitable, because the below grid produces the above “exitability grid” as well:
XX
XX
XX
XX
For the fourth query:
X N
. E
. E
. E
For the fifth query:
..XXX EENNN
...X. EEENN
...X. EEENN
...X. EEENN
This query is simply the entire grid. It cannot be determined only from whether each cell is exitable because the below grid produces the above “exitability grid” as well:
..XXX
...XX
...XX
...XX
题目大意
-
给你一个地图,
X
是障碍.
是空地 -
每次可以向左或向上移动,但不能经过任何一处障碍
-
你可以从地图最左边或最上边离开地图
-
现在有Q次询问,每次询问都将地图的第 l l l 列到第 r r r 列作为新的地图
-
在新的地图中,你可以确定出所有的
可逃离点
和不可逃离点
,并把这些点绘制成一张新的地图给别人看 -
问别人看到你这张
可否逃离点地图
后,能否唯一还原出之前的障碍空地地图
。
解题思路
这题描述有点绕
假如给你了一个
可否逃离点地图
,你看到后是否可以唯一还原出障碍空地地图
呢?如果可以唯一还原,那么每个点的信息都必须是有效的。也就是说不能通过其他点推断出这个点是否可以逃离。如果通过其他点已经确定这点必定不可逃离了,那么无论这一点的原
障碍空地地图
中是空地还是障碍,这点都是无法逃离点
,此时不能还原。那么什么时候根据其他的点就能判断这一点必定不可逃离呢?
如果这一点的上面的点和这一点的左边的点都不可逃离,那么这一点必定不可逃离,无论它是空地还是障碍。
因为这点只能向上或向左走。
此时,
可否逃离点地图
的这点必是不可逃离点
,因而无法还原出这点的原地图是空地还是障碍。
因此我们可以寻找这样的图形:
2
×
2
2\\times2
2×2的格子里,如果右上角和左下角都是障碍,那么同时包含这两列的可否逃离点地图
就不可还原。
我们可以用 O ( n m ) O(nm) O(nm)的时间复杂度的时间求出所有的这样的列,存到Swords数组中。之后给出的所有询问,只要同时包含这两列,都是No。否则就是Yes。
还有一个问题就是询问次数数量级是 2 ∗ 1 0 5 2*10^5 2∗105,而不可同时包含数组Swords的数量级也可能是 1 0 6 ( → m ) 10^6 (\\to m) 106(→m)级别,暴力求解每个询问还是要超时,因此我们还要处理一下所有的询问,把所有的询问进行离线操作。
读入了所有的询问 l l l到 r r r后,我们把询问排个序,依据是 l l l从小到大优先, r r r从小到大其次。
蓝色的横线代表排序后的询问:
假如我们在Swords中记录下了 3 3 3个值: 1 , 3 , 5 1,3,5 1,3,5(也就是说同时包含 1 ∼ 2 1\\sim2 1∼2或 3 ∼ 4 3\\sim4 3∼4或 5 ∼ 6 5\\sim6 5∼6的地图都输出No)
我们可以用一个变量to
来记录处理到了哪个询问,假如这次处理的是
1
∼
2
1\\sim2
1∼2,那么我们这次就处理所有未处理过
的且l<2
的询问。包含
1
∼
2
1\\sim2
1∼2就No,不包含就Yes。
这样下来,每个询问都只处理了一次,处理的总时间复杂度是 O ( Q ) O(Q) O(Q)(小于排序复杂度 O ( Q log Q ) O(Q\\log Q) O(QlogQ) )
AC代码
/*
* @Author: LetMeFly
* @Date: 2021-10-17 19:53:37
* @LastEditors: LetMeFly
* @LastEditTime: 2021-10-18 23:29:26
*/ // LastEditTime: 2021-10-17 20:06:52
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
char c[1000010]; // 用来输入一行
struct querys { // 询问
int l, r, th; // l到r,第th次询问
bool no; // 是否应输出No
}q[200010];
bool cmp(const querys &a, const querys &b) { // 排序规则1:l从小到大优先,r从小到大其次
if (a.l != b.l) return a.l < b.l;
if (a.r != b.r) return a.r < b.r;
return a.th < b.th;
}
bool cmp2(const querys &a, const querys &b) { // 排序规则2:按询问顺序从小到大排序(为了输出)
return a.th < b.th;
}
int main() {
int n,m;
cin>>n>>m;
vector<bool> a[n]; // 存储原始地图
for (int i = 0; i < n; i++) {
a[i].resize(m); // 每一行都有m列
}
for (int i = 0; i < n; i++) {
scanf("%s", c); // 读入这一行
for (int j = 0; j < m; j++) {
a[i][j] = c[j] == 'X'; // 处理这一行的每一列
}
}
vector<int>Swords; // 假如a在Swords中,那么同时包含第a列和第a+1列的子地图都应输出No。因每次Swords[i]都把询问一分两半,故美其名曰“宝剑”
for (int j = 0; j + 1 < m; j++) {
for (int i = 1; i < n; i++) {
if (a[i][j] && a[i - 1][j + 1]) { // 2x2的方格,左下角和右上角都是X
Swords.push_back(j); // 就存下这一列
break; // 退出循环
}
}
}
int Q;
cin>>Q; // Q次询问
for (int i = 0; i < Q; i++) {
scanf("%d%d", &q[i].l, &q[i].r);
q[i].l--, q[i].r--;
q[i].th = i;
q[i].no = false;
}
sort(q, q + Q, cmp); // 依据规则1进行排序
int to = 0; // 该处理哪个询问
for (int &left: Swords) { // 遍历Swords中的每个元素
int right = left + 1;
int newTo = to; // 这次处理之后该处理哪个询问
while (newTo < Q && q[newTo].l < right) {
newTo++;
以上是关于CodeforcesRound#749(Div.1+Div.2,basedonTechnocup2022EliminationRound1)-C. Omkar and Determination-题解的主要内容,如果未能解决你的问题,请参考以下文章
CodeforcesRound#749(Div.1.2basedonTechnocup2022EliminationRound1)-D.Omkar and the Meaning of Life-题解
Codeforces Round #749(Div. 1+Div. 2, based on Technocup 2022 Elimination Round1)-A. Windblume Ode-题解
Codeforces Round #749 (Div. 1 + Div. 2, based on Technocup 2022 Elimination Round 1) ABCD解题报告
Codeforces Round #749 (Div. 1 + Div. 2, based on Technocup 2022 Elimination Round 1) ABCD解题报告
Codeforces Round #749 (Div. 1 + Div. 2, based on Technocup 2022 Elimination Round 1) ABCD解题报告