Submission #1013292

# Submission time Handle Problem Language Result Execution time Memory
1013292 2024-07-03T11:39:30 Z boris_mihov Sky Walking (IOI19_walk) C++17
10 / 100
4000 ms 195172 KB
#include "walk.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <queue>
#include <stack>
#include <map>

typedef long long llong;
const int MAXN = 100000 + 10;
const int INTERSECTIONS = 10 + 5;
const llong INF = 1e18;
const int INTINF = 1e9;
const int MAXLOG = 17;

namespace
{
    int cnt;
    int n, m;
    int s, t;
    int h[MAXN];
    int x[MAXN];
    int left[MAXN];
    int right[MAXN];
    int y[MAXN];
    std::map <int,int> map[MAXN];
    bool vis[MAXN * INTERSECTIONS];
    llong dist[MAXN * INTERSECTIONS];
    std::vector <std::pair <int,int>> g[MAXN * INTERSECTIONS]; 
    int cntNodes;
}

struct Sparse
{
    int sparse[MAXLOG][MAXN];
    int getLOG[MAXN];

    void build(int a[])
    {
        for (int i = 1 ; i <= n ; ++i)
        {
            sparse[0][i] = a[i];
        }

        for (int lg = 1 ; (1 << lg) <= n ; ++lg)
        {
            for (int i = 1 ; i + (1 << lg) - 1 <= n ; ++i)
            {
                sparse[lg][i] = std::max(sparse[lg - 1][i], sparse[lg - 1][i + (1 << lg - 1)]);
            }
        }

        for (int i = 1 ; i <= n ; ++i)
        {
            getLOG[i] = getLOG[i - 1];
            if ((1 << getLOG[i] + 1) < i) getLOG[i]++;
        }
    }

    int findMAX(int l, int r)
    {
        int lg = getLOG[r - l + 1];
        return std::max(sparse[lg][l], sparse[lg][r - (1 << lg) + 1]);
    }
};

Sparse sparse;
llong solve()
{
    for (int i = 1 ; i <= n ; ++i)
    {
        map[i][0] = ++cnt;
    }

    sparse.build(h);
    for (int i = 1 ; i <= m ; ++i)
    {
        int prev = left[i];
        if (map[left[i]][y[i]] == 0)
        {
            map[left[i]][y[i]] = ++cnt;
        }

        while (prev < right[i])
        {
            int l = prev, r = right[i] + 1, mid;
            while (l < r - 1)
            {
                mid = l + r >> 1;
                if (sparse.findMAX(prev + 1, mid) < y[i]) l = mid;
                else r = mid;
            }

            if (map[r][y[i]] == 0)
            {
                map[r][y[i]] = ++cnt;
            }

            // std::cout << "here: " << prev << ' ' << r << ' ' << y[i] << '\n';
            g[map[prev][y[i]]].push_back({map[r][y[i]], x[r] - x[prev]});
            g[map[r][y[i]]].push_back({map[prev][y[i]], x[r] - x[prev]});
            prev = r;
        }
    }

    for (int i = 1 ; i <= n ; ++i)
    {
        auto prev = map[i].begin();
        for (auto curr = std::next(map[i].begin()) ; curr != map[i].end() ; ++curr)
        {
            // std::cout << "edge ver: " << x[i] << ' ' << prev->first << ' ' << x[i] << ' ' << curr->first << '\n';
            g[prev->second].push_back({curr->second, curr->first - prev->first});
            g[curr->second].push_back({prev->second, curr->first - prev->first});
            prev = curr;
        }
    }

    std::priority_queue <std::pair <llong,int>> pq;
    std::fill(dist + 1, dist + 1 + cnt, INF);
    pq.push({0, map[s][0]});
    dist[map[s][0]] = 0;

    while (pq.size())
    {
        auto [d, node] = pq.top();
        pq.pop();

        if (vis[node])
        {
            continue;
        }

        vis[node] = true;
        for (const auto &[u, ed] : g[node])
        {
            if (dist[u] > dist[node] + ed)
            {
                dist[u] = dist[node] + ed;
                pq.push({-dist[u], u});
            }
        }
    }

	return (dist[map[t][0]] == INF ? -1 : dist[map[t][0]]);
}

llong dp[MAXN];
llong solveSpecial()
{
    for (int i = 1 ; i <= m ; ++i)
    {
        if (left[i] == 1)
        {
            dp[i] = y[i];
        } else
        {
            dp[i] = INF;
            for (int j = 1 ; j < i ; ++j)
            {
                if (right[j] >= left[i])
                {
                    if (y[j] < y[i])
                    {
                        dp[i] = std::min(dp[i], dp[j] + x[left[i]] - x[left[j]] + y[i] - y[j]);
                    }

                    if (y[j] >= y[i] && y[j] <= h[left[i]])
                    {
                        dp[i] = std::min(dp[i], dp[j] + x[left[i]] - x[left[j]] + y[j] - y[i]);
                    }
                }
            }
        }
    }

    llong ans = INF;
    for (int i = 1 ; i <= m ; ++i)
    {
        if (right[i] == n)
        {
            ans = std::min(ans, dp[i] + x[n] - x[left[i]] + y[i]);
        }
    }

    return ans;
}

long long min_distance(std::vector<int> x, std::vector<int> h, std::vector<int> l, std::vector<int> r, std::vector<int> y, int s, int t) 
{
    n = x.size();
    m = l.size();
    ::s = s + 1; ::t = t + 1;

    for (int i = 0 ; i < n ; ++i)
    {
        ::h[i + 1] = h[i];
        ::x[i + 1] = x[i];
    }

    std::vector <int> perm(m);
    std::iota(perm.begin(), perm.end(), 0);
    std::sort(perm.begin(), perm.end(), [&](int x, int y)
    {
        return l[x] < l[y];
    });

    for (int i = 0 ; i < m ; ++i)
    {
        ::left[i + 1] = l[perm[i]] + 1;
        ::right[i + 1] = r[perm[i]] + 1;
        ::y[i + 1] = y[perm[i]];
    }

    if (::s == 1 && ::t == n) return solveSpecial();
    return solve();
}

Compilation message

walk.cpp: In member function 'void Sparse::build(int*)':
walk.cpp:51:89: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
   51 |                 sparse[lg][i] = std::max(sparse[lg - 1][i], sparse[lg - 1][i + (1 << lg - 1)]);
      |                                                                                      ~~~^~~
walk.cpp:58:33: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
   58 |             if ((1 << getLOG[i] + 1) < i) getLOG[i]++;
      |                       ~~~~~~~~~~^~~
walk.cpp: In function 'llong solve()':
walk.cpp:91:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   91 |                 mid = l + r >> 1;
      |                       ~~^~~
walk.cpp: At global scope:
walk.cpp:32:9: warning: '{anonymous}::cntNodes' defined but not used [-Wunused-variable]
   32 |     int cntNodes;
      |         ^~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 12 ms 43356 KB Output is correct
2 Correct 12 ms 43136 KB Output is correct
3 Correct 11 ms 43356 KB Output is correct
4 Correct 11 ms 43356 KB Output is correct
5 Correct 12 ms 43356 KB Output is correct
6 Correct 13 ms 43356 KB Output is correct
7 Correct 12 ms 43356 KB Output is correct
8 Correct 11 ms 43352 KB Output is correct
9 Correct 11 ms 43356 KB Output is correct
10 Correct 12 ms 43352 KB Output is correct
11 Correct 13 ms 43324 KB Output is correct
12 Correct 11 ms 43352 KB Output is correct
13 Correct 11 ms 43356 KB Output is correct
14 Correct 11 ms 43248 KB Output is correct
15 Correct 11 ms 43352 KB Output is correct
16 Correct 11 ms 43116 KB Output is correct
17 Correct 12 ms 43100 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 11 ms 43356 KB Output is correct
2 Correct 11 ms 43100 KB Output is correct
3 Correct 513 ms 139332 KB Output is correct
4 Correct 338 ms 154960 KB Output is correct
5 Correct 263 ms 140140 KB Output is correct
6 Correct 195 ms 129360 KB Output is correct
7 Correct 213 ms 140108 KB Output is correct
8 Correct 669 ms 166160 KB Output is correct
9 Correct 259 ms 137812 KB Output is correct
10 Correct 555 ms 195172 KB Output is correct
11 Correct 201 ms 98132 KB Output is correct
12 Correct 1530 ms 53572 KB Output is correct
13 Incorrect 1734 ms 53588 KB Output isn't correct
14 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 470 ms 46056 KB Output is correct
2 Execution timed out 4050 ms 48988 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 470 ms 46056 KB Output is correct
2 Execution timed out 4050 ms 48988 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 12 ms 43356 KB Output is correct
2 Correct 12 ms 43136 KB Output is correct
3 Correct 11 ms 43356 KB Output is correct
4 Correct 11 ms 43356 KB Output is correct
5 Correct 12 ms 43356 KB Output is correct
6 Correct 13 ms 43356 KB Output is correct
7 Correct 12 ms 43356 KB Output is correct
8 Correct 11 ms 43352 KB Output is correct
9 Correct 11 ms 43356 KB Output is correct
10 Correct 12 ms 43352 KB Output is correct
11 Correct 13 ms 43324 KB Output is correct
12 Correct 11 ms 43352 KB Output is correct
13 Correct 11 ms 43356 KB Output is correct
14 Correct 11 ms 43248 KB Output is correct
15 Correct 11 ms 43352 KB Output is correct
16 Correct 11 ms 43116 KB Output is correct
17 Correct 12 ms 43100 KB Output is correct
18 Correct 11 ms 43356 KB Output is correct
19 Correct 11 ms 43100 KB Output is correct
20 Correct 513 ms 139332 KB Output is correct
21 Correct 338 ms 154960 KB Output is correct
22 Correct 263 ms 140140 KB Output is correct
23 Correct 195 ms 129360 KB Output is correct
24 Correct 213 ms 140108 KB Output is correct
25 Correct 669 ms 166160 KB Output is correct
26 Correct 259 ms 137812 KB Output is correct
27 Correct 555 ms 195172 KB Output is correct
28 Correct 201 ms 98132 KB Output is correct
29 Correct 1530 ms 53572 KB Output is correct
30 Incorrect 1734 ms 53588 KB Output isn't correct
31 Halted 0 ms 0 KB -