思路:分块dp, 对于修改将对应的块再dp一次。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 1e5 + 7; const int M = 1e7 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1000000007; int n, m, q, block[N], L[N], R[N]; char s[N][11], op[3]; PII f[N][11]; PII dp(int x, int y, char c, int B) { if(x == L[B] - 1 || y == 0 || y == m + 1) return mk(x, y); if(f[x][y].fi || f[x][y].se) return f[x][y]; if(s[x][y] == '>' && c == '<') return f[x][y] = mk(-1, -1); if(s[x][y] == '<' && c == '>') return f[x][y] = mk(-1, -1); if(s[x][y] == '>') return f[x][y] = dp(x, y + 1, s[x][y], B); if(s[x][y] == '<') return f[x][y] = dp(x, y - 1, s[x][y], B); return f[x][y] = dp(x - 1, y, s[x][y], B); } void update(int B) { for(int i = L[B]; i <= R[B]; i++) for(int j = 1; j <= m; j++) dp(i, j, '^', B); } int main() { memset(L, -1, sizeof(L)); memset(R, -1, sizeof(R)); scanf("%d%d%d", &n, &m, &q); for(int i = 1; i <= n; i++) { block[i] = i / 300; if(L[block[i]] == -1) L[block[i]] = i; R[block[i]] = i; } for(int i = 1; i <= n; i++) { scanf("%s", s[i] + 1); } for(int i = 0; i <= n / 300; i++) update(i); while(q--) { int x, y; scanf("%s%d%d", op, &x, &y); if(op[0] == 'C') { scanf("%s", op); s[x][y] = op[0]; int p = x / 300; for(int i = L[p]; i <= R[p]; i++) memset(f[i], 0, sizeof(f[i])); update(p); } else { while((x != -1) && (x >= 1 && x <= n && y >= 1 && y <= m)) { int ntx = f[x][y].fi; int nty = f[x][y].se; x = ntx; y = nty; } printf("%d %d\n", x, y); } } return 0; } /* */