F
在线复杂度高就离线
每个点都是由下或右去转移的,只用记录两层节点即可,相当于是一个滚动数组。
对于每个节点来说,用一个bitset存图,用来记录当前点是否可以到达地图上的某个点。
更新完该点的bitset后更新从该点出发的答案。
#include <bits/stdc++.h>
using namespace std;
const int N = 510, M = 500050;
#define node(x, y) x * m + y
int n, m, k;
char z[N][N];
bitset <N*N> p[2][N];
vector <pair <int, int>> q[N][N];
int ans[M], bad[M];
int main() {
int l, x1, x2, y1, y2;
scanf("%d%d", &n, &m);
for(int i = 0;i < n;i ++) {
scanf("%s", z[i]);
}
scanf("%d", &k);
for(int i = 0;i < k;i ++) {
scanf("%d%d%d%d%d", &l, &x1, &y1, &x2, &y2);
x1 --, x2 --, y1 --, y2 --;
if(l == 1)
if(y1 == y2) q[x1][y1].emplace_back(node(x2, y2), i);
else bad[i] = 1;
if(l == 2)
if(x1 == x2) q[x1][y1].emplace_back(node(x2, y2), i);
else bad[i] = 1;
else q[x1][y1].emplace_back(node(x2, y2), i);;
}
int v = 0;
for(int i = n-1;i >= 0;i --) {
v ^= 1;
for(int j = m-1;j >= 0;j --) {
if(z[i][j] == '0') p[v][j] = p[v][j + 1] | p[v ^ 1][j], p[v][j].set(node(i, j));
else p[v][j].reset();
for(auto [no, id] : q[i][j]){
ans[id] = p[v][j][no];
}
}
}
for(int i = 0;i < k;i ++) {
// printf("%d %d ", bad[i], ans[i]);
if(bad[i]) puts("no");
else if(ans[i]) puts("yes");
else puts("no");
}
return 0;
}