Submission #780322

# Submission time Handle Problem Language Result Execution time Memory
780322 2023-07-12T08:16:55 Z boris_mihov Maze (JOI23_ho_t3) C++17
0 / 100
2000 ms 1817364 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)
    {
        assert(pos >= 1 && pos < (int)tree.size());
        for (int idx = pos ; idx < (int)tree.size() ; idx += idx & (-idx))
        {
            tree[idx] += value;
        }
    }

    int query(int pos)
    {
        assert(pos >= 0 && pos < (int)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) < (int)tree.size() && (1 << log) - tree[idx + (1 << log)] < k)
            {
                idx += (1 << log);
                k -= (1 << log) - tree[idx];
            }
        }

        int l = 0, r = (int)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);
        assert(r < (int)tree.size());
        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)
{
    if (dist[row][col] == INF)
    {
        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 (curr < byROW[row].query(c))
    {
        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);
    }
}

void addCOL(int col, int rowL, int rowR, int currDist)
{
    int curr = byCOL[col].query(rowL - 1);
    while (curr < byCOL[col].query(r))
    {
        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);
    }
}

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;
}
# Verdict Execution time Memory Grader output
1 Execution timed out 2122 ms 1408508 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 2138 ms 1739316 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 2122 ms 1817364 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 2138 ms 1739316 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 2138 ms 1739316 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 2122 ms 1408508 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 2122 ms 1408508 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 2122 ms 1408508 KB Time limit exceeded
2 Halted 0 ms 0 KB -