题目大意:
n
∗
m
n*m
n∗m的矩阵,
a
i
,
j
a_{i,j}
ai,j为
1
1
1则无障碍,否则有障碍,
q
q
q个操作,
操作有两种情况:
[
1
,
(
x
,
y
)
]
[1,(x,y)]
[1,(x,y)]表示将点
(
x
,
y
)
(x,y)
(x,y)取反,有障碍变成无,无变成有
[
2
,
(
a
,
b
)
,
(
x
,
y
)
]
[2,(a,b),(x,y)]
[2,(a,b),(x,y)],回答从
(
a
,
b
)
(a,b)
(a,b)走到
(
x
,
y
)
(x,y)
(x,y)的最短距离,无解输出-1
只能向上下右三个方向走
1
<
=
n
<
=
5
,
1
<
=
m
<
=
2
e
5
,
q
<
=
5
e
4
1<=n<=5,1<=m<=2e5,q<=5e4
1<=n<=5,1<=m<=2e5,q<=5e4
分析:
类似https://blog.csdn.net/Gx_Man_VIP/article/details/99640286
多了一个修改操作,就是修改完后将对应的叶子节点的
f
f
f改了,然后向上维护沿路的
f
f
f即可
代码:
#pragma GCC optimize(3)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <set>
#include <queue>
#include <cstring>
#include <algorithm>
#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)
#define lson(x) x * 2
#define rson(x) x * 2 + 1
#define mt(x) memset(x, 0x3f, sizeof(x))
#define mp(x, y) memcpy(x, y, sizeof(y))
#define inf 0x3f3f3f3f
#define N 200005
#define M 6
using namespace std;
struct Matrix {
int a[M][M];
}cc, ans;
struct Node {
Matrix s;
}C[N*5];
int er[M][N], n, m, q;
bool flag;
typedef long long ll;
Matrix operator * (Matrix &aa, Matrix &bb) {
mt(cc.a);
rep(i, 1, n)
rep(j, 1, n)
rep(k, 1, n) cc.a[i][j] = min(cc.a[i][j], aa.a[i][k] + bb.a[k][j] + 1);
return cc;
}
void update(int x) {
C[x].s = C[lson(x)].s * C[rson(x)].s;
}
void Build(int x, int l, int r) {
if (l == r) {
mt(C[x].s.a);
rep(i, 1, n) {
if (!er[i][l]) continue;
rep(j, i, n) if (er[j][l]) C[x].s.a[j][i] = C[x].s.a[i][j] = j - i; else break;
}
return;
}
int mid = (l + r) >> 1;
Build(lson(x), l, mid);
Build(rson(x), mid + 1, r);
update(x);
}
void change(int x, int l, int r, int pos) {
if (l == r) {
mt(C[x].s.a);
rep(i, 1, n) {
if (!er[i][l]) continue;
rep(j, i, n) if (er[j][l]) C[x].s.a[j][i] = C[x].s.a[i][j] = j - i; else break;
}
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) change(lson(x), l, mid, pos); else change(rson(x), mid + 1, r, pos);
update(x);
}
void Work(int x, int l, int r, int p, int q) {
if (p == l && q == r) {
if (!flag) ans = C[x].s, flag = 1; else ans = ans * C[x].s;
return;
}
int mid = (l + r) >> 1;
if (q <= mid) Work(lson(x), l, mid, p, q);
else if (p > mid) Work(rson(x), mid + 1, r, p, q);
else Work(lson(x), l, mid, p, mid), Work(rson(x), mid + 1, r, mid + 1, q);
}
int main() {
freopen("maze.in", "r", stdin);
freopen("maze.out", "w", stdout);
scanf("%d %d %d", &n, &m, &q);
rep(i, 1, n)
rep(j, 1, m) scanf("%d", &er[i][j]);
Build(1, 1, m);
int opt, AX, AY, BX, BY;
while (q--) {
scanf("%d", &opt);
if (opt == 1) {
scanf("%d %d", &AX, &AY);
er[AX][AY] ^= 1;
change(1, 1, m, AY);
} else {
scanf("%d %d %d %d", &AX, &AY, &BX, &BY);
if (BY < AY) {
printf("-1\n");
} else
if (BY == AY) {
bool check = 1;
rep(i, min(AX, BX), max(AX, BX))
if (!er[i][AY]) { check = 0; break; }
if (check) printf("%d\n", abs(AX - BX)); else printf("-1\n");
} else {
flag = 0;
Work(1, 1, m, AY, BY);
if (ans.a[AX][BX] != inf) printf("%d\n", ans.a[AX][BX]); else printf("-1\n");
}
}
}
return 0;
}