Submission #448086

# Submission time Handle Problem Language Result Execution time Memory
448086 2021-07-28T19:09:58 Z blue Sky Walking (IOI19_walk) C++17
0 / 100
4000 ms 35148 KB
#include "walk.h"
#include <set>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxN = 100'000;
const int maxM = 100'000;
const int lg = 19;
const long long INF = 1'000'000'000'000'000'000LL;

int N;
vector<int> X;
vector<int> H;

int M;
vector<int> L;
vector<int> R;
vector<int> Y;

const int S = maxM;
const int G = maxM + 1;
const int no_skywalk = -1;






bool skywalk_comp(int p, int q) //compare skywalks by height
{
    if(p == no_skywalk) return 1; //-1 -> height = -INF
    else if(q == no_skywalk) return 0;
    else if(Y[p] == Y[q]) return p < q;
    else return Y[p] < Y[q];
}

bool skywalk_leq(int p, int q)
{
    if(p == no_skywalk) return 1; //-1 -> height = -INF
    else if(q == no_skywalk) return 0;
    else if(Y[p] == Y[q]) return p <= q;
    else return Y[p] <= Y[q];
}

int max_skywalk(int p, int q)
{
    if(skywalk_comp(p, q)) return q;
    else return p;
}

int min_skywalk(int p, int q)
{
    if(p == no_skywalk) return q;
    else if(q == no_skywalk) return p;
    return p + q - max_skywalk(p, q);
}



struct segtree
{
    int l;
    int r;
    vector<int> w; //skywalks sorted by height

    segtree* left = NULL;
    segtree* right = NULL;


    segtree()
    {
        ;
    }

    segtree(int L, int R)
    {
        l = L;
        r = R;

        if(l == r) return;

        int m = (l+r)/2;

        left = new segtree(l, m);
        right = new segtree(m+1, r);
    }

    void add_skywalk(int i) //over L[i] to R[i];
    {
        if(R[i] < l || r < L[i]) return;
        else if(L[i] <= l && r <= R[i])
        {
            w.push_back(i);
        }
        else
        {
            left->add_skywalk(i);
            right->add_skywalk(i);
        }
    }

    void sort_skywalks()
    {
        sort(w.begin(), w.end(), skywalk_comp);

        if(l != r)
        {
            left->sort_skywalks();
            right->sort_skywalks();
        }
    }

    int locate_lower(int I, int J) //building i, skywalk j
    {
        //if(I < L[J] || R[J] < I) return -1; //guaranteed;
        if(I < l || r < I) return no_skywalk;
        else
        {
            int ind = -1;
            for(int bit = lg; bit >= 0; bit--)
            {
                if(ind + (1 << bit) >= w.size()) continue;
                if(!skywalk_comp(w[ind + (1 << bit)], J)) continue;
                ind += (1 << bit);
            }

            // if(ind != -1 && w[ind] == I) ind--;

            int curr_walk = (ind == -1) ? no_skywalk : w[ind];

            int deeper_walk;
            if(l == r) deeper_walk = no_skywalk;
            else deeper_walk = max_skywalk(left->locate_lower(I, J), right->locate_lower(I, J));

            return max_skywalk(curr_walk, deeper_walk);
        }
    }

    int locate_higher(int I, int J) //building i, skywalk j
    {
        //if(I < L[J] || R[J] < I) return -1; //guaranteed;
        if(I < l || r < I) return no_skywalk;
        else
        {
            int ind = -1;
            for(int bit = lg; bit >= 0; bit--)
            {
                if(ind + (1 << bit) >= w.size()) continue;
                if(!skywalk_leq(w[ind + (1 << bit)], J)) continue;
                ind += (1 << bit);
            }
            ind++;

            int curr_walk = (ind >= w.size() ? no_skywalk : w[ind]);

            int deeper_walk;
            if(l == r) deeper_walk = no_skywalk;
            else deeper_walk = min_skywalk(left->locate_higher(I, J), right->locate_higher(I, J));

            return min_skywalk(curr_walk, deeper_walk);
        }
    }
};




vector<int> edge[maxM + 3];
vector<long long> dist[maxM + 3];

void add_edge(int u, int v, long long w)
{
    cerr << "add edge " << u << ' ' << v << ' ' << w << '\n';
    edge[u].push_back(v);
    dist[u].push_back(w);
}

vector<long long> distS(maxM + 3, INF);

struct pos
{
    int i;
};

bool operator < (pos A, pos B)
{
    if(distS[A.i] == distS[B.i]) return A.i < B.i;
    return distS[A.i] < distS[B.i];
}



long long min_distance(vector<int> x, vector<int> h, vector<int> l, vector<int> r, vector<int> y, int s, int g)
{
    N = x.size();
    X = x;
    H = h;

    M = l.size();
    L = l;
    R = r;
    Y = y;

    //source = 0, destination = n-1
    segtree ST(0, N-1);
    for(int j = 0; j < M; j++)
        ST.add_skywalk(j);

    ST.sort_skywalks();


    for(int j = 0; j < M; j++)
    {
        cerr << "j = " << j << ' ' << L[j] << ' ' << R[j] << '\n';
        int top_walk = ST.locate_higher(R[j], j);
        if(top_walk != no_skywalk)
        {
            cerr << "t1\n";
            add_edge(j, top_walk, X[ R[top_walk] ] - X[ R[j] ] + Y[top_walk] - Y[j]);
        }

        int bottom_walk = ST.locate_lower(R[j], j);
        // cerr << "locate lower " << R[j] << ' ' << j << ' ' << r_w << '\n';
        if(bottom_walk != no_skywalk)
        {
            // cerr << "t2\n";
            add_edge(j, bottom_walk, X[ R[bottom_walk] ] - X[ R[j] ] + Y[j] - Y[bottom_walk]);
        }

        if(L[j] == 0)
        {
            add_edge(S, j, X[ R[j] ] - X[0] + Y[j]);
            cerr << "S " << j << ' ' << R[j] << ' ' << X[R[j]] << ' ' << X[0] << ' ' << Y[j] << '\n';
        }

        if(R[j] == N-1)
            add_edge(j, G, Y[j]);
    }


    distS[S] = 0;
    set<pos> tbv;
    for(int j = 0; j < M; j++) tbv.insert(pos{j});
    tbv.insert(pos{S});
    tbv.insert(pos{G});

    while(!tbv.empty())
    {
        int u = tbv.begin()->i;
        tbv.erase(tbv.begin());

        for(int e = 0; e < edge[u].size(); e++)
        {
            int v = edge[u][e];
            long long wt = dist[u][e];

            if(distS[v] > distS[u] + wt)
            {
                tbv.erase(pos{v});
                // cerr << u << ' ' << v << ' ' << distS[u] + wt << '\n';
                distS[v] = distS[u] + wt;
                tbv.insert(pos{v});
            }
        }
    }

    // for(int j = 0; j < M; j++) cerr << j << ' ' << distS[j] << '\n';
    // cerr << "S " << distS[S] << '\n';
    // cerr << "G " << distS[G] << '\n';

    // for(int j = 0; j < M; j++) cerr << "dist " << j << " = " << distS[j] << '\n';

    if(distS[G] == INF) distS[G] = -1;

    return distS[G];
}

Compilation message

walk.cpp: In member function 'int segtree::locate_lower(int, int)':
walk.cpp:123:37: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  123 |                 if(ind + (1 << bit) >= w.size()) continue;
      |                    ~~~~~~~~~~~~~~~~~^~~~~~~~~~~
walk.cpp: In member function 'int segtree::locate_higher(int, int)':
walk.cpp:149:37: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  149 |                 if(ind + (1 << bit) >= w.size()) continue;
      |                    ~~~~~~~~~~~~~~~~~^~~~~~~~~~~
walk.cpp:155:34: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  155 |             int curr_walk = (ind >= w.size() ? no_skywalk : w[ind]);
      |                              ~~~~^~~~~~~~~~~
walk.cpp: In function 'long long int min_distance(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, int, int)':
walk.cpp:253:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  253 |         for(int e = 0; e < edge[u].size(); e++)
      |                        ~~^~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Incorrect 4 ms 5708 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 3 ms 5708 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1705 ms 18732 KB Output is correct
2 Correct 3973 ms 31632 KB Output is correct
3 Execution timed out 4085 ms 35148 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1705 ms 18732 KB Output is correct
2 Correct 3973 ms 31632 KB Output is correct
3 Execution timed out 4085 ms 35148 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 4 ms 5708 KB Output isn't correct
2 Halted 0 ms 0 KB -