给一个2*n 的地图,有一些X不能走,没有修改,m个询问,问一个点到另一个点的最短距离。
n , m < = 2 e 5 n,m<=2e5 n,m<=2e5
在线段树上dp,
某个节点 i i i表示了区间 [ l , r ] [l,r] [l,r]( l l l列到 r r r列)
这里设 f i , j f_{i,j} fi,j表示第 i i i行的左端点到第 j j j行的右端点的最短距离(不能走超过 l l l列或超过 r r r列)
然后转移就是从左右儿子中的 f f f转移过来,类似矩阵乘法
f i , j = m i n f_{i,j}=min fi,j=min{ f l s o n i , k + f r s o n k , j + 1 flson_{i,k}+frson_{k,j}+1 flsoni,k+frsonk,j+1}
每次询问的时候就找到这两个点所包括的行列,然后将他们的 f i , j f_{i,j} fi,j合并出来
然后回答即可
#pragma GCC optimize(3)
#include
#include
#include
#include
#include
#include
#include
#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 3
using namespace std;
struct Matrix {
int a[M][M];
}cc, ans;
struct Node {
Matrix s;
}C[N*5];
int er[M][N], m, q;
bool flag;
typedef long long ll;
Matrix operator * (Matrix &aa, Matrix &bb) {
mt(cc.a);
rep(i, 1, 2)
rep(j, 1, 2)
rep(k, 1, 2) 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, 2) {
if (!er[i][l]) continue;
rep(j, i, 2) 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 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() {
scanf("%d %d", &m, &q);
char ch[N];
rep(i, 1, 2) {
scanf("%s", ch + 1);
rep(j, 1, m) er[i][j] = (ch[j] == '.') ? 1 : 0;
}
Build(1, 1, m);
int opt, AX, AY, BX, BY, AA, BB;
while (q--) {
scanf("%d %d", &AA, &BB);
if (AA > m) AX = 2, AY = AA - m; else AX = 1, AY = AA;
if (BB > m) BX = 2, BY = BB - m; else BX = 1, BY = BB;
if (AY > BY) swap(AY, BY), swap(AX, BX);
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;
}