답안 #770741

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
770741 2023-07-01T20:38:52 Z boris_mihov Maze (JOI23_ho_t3) C++17
0 / 100
291 ms 610868 KB
#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)
    {
        for (int idx = pos ; idx < tree.size() ; idx += idx & (-idx))
        {
            tree[idx] += value;
        }
    }

    int query(int pos)
    {
        int res = 0;
        for (int idx = pos ; idx > 0 ; idx -= idx & (-idx))
        {
            res += tree[idx];
        }

        return pos - res;
    }

    int findKth(int 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];
            }
        }

        return idx + 1;
    }
};

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;
        }

        dist[row][search] = currDist + 1;
        dq.push_back({row, search});
        setCELL(row, search);
    }
}

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;
        }

        dist[search][col] = currDist + 1;
        dq.push_back({search, col});
        setCELL(search, 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;
}

Compilation message

Main.cpp: In member function 'void BIT::update(int, int)':
Main.cpp:23:34: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   23 |         for (int idx = pos ; idx < tree.size() ; idx += idx & (-idx))
      |                              ~~~~^~~~~~~~~~~~~
Main.cpp: In member function 'int BIT::findKth(int)':
Main.cpp:45:34: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   45 |             if (idx + (1 << log) < tree.size() && (1 << log) - tree[idx + (1 << log)] < k)
      |                 ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 291 ms 610868 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 242 ms 610864 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 244 ms 610760 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 242 ms 610864 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 242 ms 610864 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 291 ms 610868 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 291 ms 610868 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 291 ms 610868 KB Output isn't correct
2 Halted 0 ms 0 KB -