Use this to learn the idea, then write your own version.
1class SegmentTree {2 public:3 explicit SegmentTree(int n, int kInf) : kInf(kInf), n(n), tree(4 * n, kInf) {}4 5 6 void update(int i, int val) {7 update(0, 0, n - 1, i, val);8 }9 10 11 int query(int i, int j) const {12 return query(0, 0, n - 1, i, j);13 }14 15 private:16 const int kInf; 17 const int n; 18 vector<int> tree; 19 20 void update(int treeIndex, int lo, int hi, int i, int val) {21 if (lo == hi) {22 tree[treeIndex] = val;23 return;24 }25 const int mid = (lo + hi) / 2;26 if (i <= mid)27 update(2 * treeIndex + 1, lo, mid, i, val);28 else29 update(2 * treeIndex + 2, mid + 1, hi, i, val);30 tree[treeIndex] = merge(tree[2 * treeIndex + 1], tree[2 * treeIndex + 2]);31 }32 33 int query(int treeIndex, int lo, int hi, int i, int j) const {34 if (i <= lo && hi <= j) 35 return tree[treeIndex];36 if (j < lo || hi < i) 37 return kInf;38 const int mid = (lo + hi) / 2;39 return merge(query(treeIndex * 2 + 1, lo, mid, i, j),40 query(treeIndex * 2 + 2, mid + 1, hi, i, j));41 }42 43 int merge(int left, int right) const {44 return min(left, right);45 }46};47 48class Solution {49 public:50 int minimumVisitedCells(vector<vector<int>>& grid) {51 const int m = grid.size();52 const int n = grid[0].size();53 const int kInf = (m + n) * 2 - 1;54 vector<SegmentTree> rows(m, SegmentTree(n, kInf));55 vector<SegmentTree> cols(n, SegmentTree(m, kInf));56 57 58 rows[m - 1].update(n - 1, 1);59 cols[n - 1].update(m - 1, 1);60 61 for (int i = m - 1; i >= 0; --i)62 for (int j = n - 1; j >= 0; --j) {63 64 65 if (grid[i][j] == 0)66 continue;67 const int moveRight = rows[i].query(j + 1, grid[i][j] + j);68 const int moveDown = cols[j].query(i + 1, grid[i][j] + i);69 const int minMove = min(kInf, min(moveRight, moveDown) + 1);70 rows[i].update(j, minMove);71 cols[j].update(i, minMove);72 }73 74 const int res = rows[0].query(0, 0);75 return res == kInf ? -1 : res;76 }77};78