제출 #780295

#제출 시각아이디문제언어결과실행 시간메모리
780295boris_mihovMaze (JOI23_ho_t3)C++17
0 / 100
625 ms1138160 KiB
#include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <vector> #include <queue> typedef long long llong; const int MAXLOG = 23; const int MAXN = 6000000 + 10; const int INF = 1e9; struct BIT { std::vector <int> tree; void build(int sz) { tree.resize(sz + 1, 0); } void update(int pos, int value) { assert(pos >= 1 && pos < tree.size()); for (int idx = pos ; idx < tree.size() ; idx += idx & (-idx)) { tree[idx] += value; } } int query(int pos) { assert(pos >= 0 && pos < tree.size()); int res = 0; for (int idx = pos ; idx > 0 ; idx -= idx & (-idx)) { res += tree[idx]; } return pos - res; } int findKth(int k) { int k2 = k; int idx = 0; for (int log = MAXLOG - 1 ; log >= 0 ; --log) { if (idx + (1 << log) < tree.size() && (1 << log) - tree[idx + (1 << log)] < k) { idx += (1 << log); k -= (1 << log) - tree[idx]; } } int l = 0, r = tree.size(), mid; while (l < r - 1) { mid = (l + r) / 2; if (query(mid) < k2) l = mid; else r = mid; } // if (l != idx) // { // std::cout << "bad: " << l << ' ' << idx << '\n' << std::flush; // } // assert(l == idx); return r; } }; int r, c, n; int sRow, sCol; int eRow, eCol; BIT byROW[MAXN]; BIT byCOL[MAXN]; std::pair <int,int> delta[] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}}; std::deque <std::pair <int,int>> dq; std::vector <int> dist[MAXN]; std::string t[MAXN]; bool isOutside(int row, int col) { return row == 0 || row == r + 1 || col == 0 || col == c + 1; } void setCELL(int row, int col) { byROW[row].update(col, 1); byCOL[col].update(row, 1); } void addROW(int row, int colL, int colR, int currDist) { int curr = byROW[row].query(colL - 1); // while (true) // { // int search = byROW[row].findKth(curr + 1); // if (search > colR) // { // break; // } // if (dist[row][search] > currDist + 1) dist[row][search] = currDist + 1; // dq.push_back({row, search}); // setCELL(row, search); // } for (int i = colL ; i <= colR ; ++i) { if (dist[row][i] == INF) { if (byROW[row].findKth(curr + 1) != i) { assert(false); int res = byROW[row].findKth(curr + 1); assert(res != i); // // assert(byROW[row].query(res) - byROW[row].query(res - 1) == 1); // bool was = (res > i); while (res < i){} while (res > i){} // assert(res != i && (res > i) == was); // // while (true) assert((res > i) == was); } setCELL(row, i); dist[row][i] = currDist + 1; dq.push_back({row, i}); } } } void addCOL(int col, int rowL, int rowR, int currDist) { int curr = byCOL[col].query(rowL - 1); // while (true) // { // int search = byCOL[col].findKth(curr + 1); // if (search > rowR) // { // break; // } // if (dist[search][col] > currDist + 1) dist[search][col] = currDist + 1; // dq.push_back({search, col}); // setCELL(search, col); // } for (int i = rowL ; i <= rowR ; ++i) { if (dist[i][col] == INF) { if (byCOL[col].findKth(curr + 1) != i) { // assert(false); int res = byCOL[col].findKth(curr + 1); assert(res != i); // // assert(byCOL[col].query(res) - byCOL[col].query(res - 1) == 1); // bool was = (res > i); while (res < i){} while (res > i){} // assert(res != i && (res > i) == was); // // while (true) assert((res > i) == was); } setCELL(i, col); dist[i][col] = currDist + 1; dq.push_back({i, col}); } } } void solve() { for (int i = 1 ; i <= r ; ++i) { std::fill(dist[i].begin(), dist[i].end(), INF); } for (int i = 1 ; i <= r ; ++i) { byROW[i].build(c); } for (int i = 1 ; i <= c ; ++i) { byCOL[i].build(r); } dq.push_back({sRow, sCol}); dist[sRow][sCol] = 0; setCELL(sRow, sCol); while (!dq.empty()) { auto [row, col] = dq.front(); dq.pop_front(); if (row == eRow && col == eCol) { std::cout << dist[row][col] << '\n'; break; } for (const auto &[dx, dy] : delta) { if (isOutside(row + dx, col + dy) || dist[row + dx][col + dy] <= dist[row][col]) { continue; } if (t[row + dx][col + dy] == '.') { setCELL(row + dx, col + dy); dist[row + dx][col + dy] = dist[row][col]; dq.push_front({row + dx, col + dy}); } } if (abs(row - eRow) <= n && abs(col - eCol) <= n && dist[eRow][eCol] > dist[row][col]) { setCELL(eRow, eCol); dist[eRow][eCol] = dist[row][col] + 1; dq.push_back({eRow, eCol}); } addROW(std::max(1, row - n), std::max(1, col - n + 1), std::min(c, col + n - 1), dist[row][col]); addROW(std::min(r, row + n), std::max(1, col - n + 1), std::min(c, col + n - 1), dist[row][col]); addCOL(std::max(1, col - n), std::max(1, row - n + 1), std::min(r, row + n - 1), dist[row][col]); addCOL(std::min(c, col + n), std::max(1, row - n + 1), std::min(r, row + n - 1), dist[row][col]); } } void input() { std::cin >> r >> c >> n; std::cin >> sRow >> sCol; std::cin >> eRow >> eCol; for (int i = 1 ; i <= r ; ++i) { std::cin >> t[i]; t[i] = ' ' + t[i]; dist[i].resize(c + 1, INF); } } void fastIOI() { std::ios_base :: sync_with_stdio(0); std::cout.tie(nullptr); std::cin.tie(nullptr); } int main() { fastIOI(); input(); solve(); return 0; }

컴파일 시 표준 에러 (stderr) 메시지

In file included from /usr/include/c++/10/cassert:44,
                 from Main.cpp:4:
Main.cpp: In member function 'void BIT::update(int, int)':
Main.cpp:23:32: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   23 |         assert(pos >= 1 && pos < tree.size());
      |                            ~~~~^~~~~~~~~~~~~
Main.cpp:24:34: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   24 |         for (int idx = pos ; idx < tree.size() ; idx += idx & (-idx))
      |                              ~~~~^~~~~~~~~~~~~
In file included from /usr/include/c++/10/cassert:44,
                 from Main.cpp:4:
Main.cpp: In member function 'int BIT::query(int)':
Main.cpp:32:32: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   32 |         assert(pos >= 0 && pos < tree.size());
      |                            ~~~~^~~~~~~~~~~~~
Main.cpp: In member function 'int BIT::findKth(int)':
Main.cpp:48:34: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   48 |             if (idx + (1 << log) < tree.size() && (1 << log) - tree[idx + (1 << log)] < k)
      |                 ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...