제출 #760519

#제출 시각아이디문제언어결과실행 시간메모리
760519Kihihihi밀림 점프 (APIO21_jumps)C++17
48 / 100
1238 ms66664 KiB
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cassert>
#include <ctime>
#include <chrono>
#include <cstdio>
#include <random>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <deque>
#include <queue>
#include <bitset>
#include <list>
#include <fstream>
#include <functional>
#include <complex>
#include "jumps.h"
using namespace std;
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());

const int INF = 1e9, MOD = 1e9 + 7, MOD2 = 998244353, LOG = 20;
const long double EPS = 1e-9, PI = acos(-1);

struct sparse_table
{
    int n;
    vector<int> h, lg2;
    vector<vector<int>> t;

    sparse_table() {}

    sparse_table(vector<int>& in)
    {
        n = in.size();
        h = in;
        lg2.resize(n + 1);
        for (int i = 2; i < n + 1; i++)
        {
            lg2[i] = lg2[i / 2] + 1;
        }

        t.resize(lg2[n] + 1);
        t[0].resize(n);
        iota(t[0].begin(), t[0].end(), 0);
        for (int i = 1; i < t.size(); i++)
        {
            int len = (1ll << i);
            t[i].resize(n - len + 1);
            for (int j = 0; j < t[i].size(); j++)
            {
                if (h[t[i - 1][j]] > h[t[i - 1][j + len / 2]])
                {
                    t[i][j] = t[i - 1][j];
                }
                else
                {
                    t[i][j] = t[i - 1][j + len / 2];
                }
            }
        }
    }

    int get(int l, int r)
    {
        int lg = lg2[r - l + 1];
        if (h[t[lg][l]] > h[t[lg][r - (1ll << lg) + 1]])
        {
            return t[lg][l];
        }
        else
        {
            return t[lg][r - (1ll << lg) + 1];
        }
    }
};

sparse_table sptb;
vector<int> v, gtl, gtr;
vector<vector<int>> bingt, binls;

void init(int n, std::vector<int> h)
{
    v = h;
    sptb = sparse_table(h);

    gtl.resize(n, -1);
    vector<int> st;
    for (int i = 0; i < n; i++)
    {
        while (st.size() && v[st.back()] <= v[i])
        {
            st.pop_back();
        }
        if (st.size())
        {
            gtl[i] = st.back();
        }
        st.push_back(i);
    }

    gtr.resize(n, n);
    st = {};
    for (int i = n - 1; i > -1; i--)
    {
        while (st.size() && v[st.back()] <= v[i])
        {
            st.pop_back();
        }
        if (st.size())
        {
            gtr[i] = st.back();
        }
        st.push_back(i);
    }

    bingt.resize(n, vector<int>(LOG, -1));
    binls.resize(n, vector<int>(LOG, -1));
    for (int i = 0; i < n; i++)
    {
        if (gtl[i] == -1 && gtr[i] == n)
        {
            continue;
        }

        if (gtl[i] == -1)
        {
            bingt[i][0] = binls[i][0] = gtr[i];
        }
        if (gtr[i] == n)
        {
            bingt[i][0] = binls[i][0] = gtl[i];
        }
        if (gtl[i] != -1 && gtr[i] != n)
        {
            if (v[gtl[i]] > v[gtr[i]])
            {
                bingt[i][0] = gtl[i];
                binls[i][0] = gtr[i];
            }
            else
            {
                bingt[i][0] = gtr[i];
                binls[i][0] = gtl[i];
            }
        }
    }
    for (int i = 1; i < LOG; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (binls[j][i - 1] != -1)
            {
                binls[j][i] = binls[binls[j][i - 1]][i - 1];
            }
            if (bingt[j][i - 1] != -1)
            {
                bingt[j][i] = bingt[bingt[j][i - 1]][i - 1];
            }
        }
    }
}

int minimum_jumps(int a, int b, int c, int d)
{
    int mxto = sptb.get(c, d);
    int bsl = a - 1, bsr = b + 1;
    while (bsr - bsl > 1)
    {
        int mid = (bsl + bsr) / 2;
        if (v[sptb.get(mid, b)] < v[mxto])
        {
            bsr = mid;
        }
        else
        {
            bsl = mid;
        }
    }
    if (bsr == b + 1)
    {
        return -1;
    }
    a = bsr;

    if (b < c - 1)
    {
        if (v[sptb.get(b + 1, c - 1)] > v[mxto])
        {
            return -1;
        }
    }
    d = mxto;

    int fr = sptb.get(a, b);
    int maxleft = v[fr];
    if (b < c - 1)
    {
        maxleft = max(maxleft, v[sptb.get(b + 1, c - 1)]);
    }

    bsl = c - 1; bsr = d;
    while (bsr - bsl > 1)
    {
        int mid = (bsl + bsr) / 2;
        if (maxleft < v[sptb.get(c, mid)])
        {
            bsr = mid;
        }
        else
        {
            bsl = mid;
        }
    }
    int to = bsr;

    int ans = 0;
    for (int i = LOG - 1; i > -1; i--)
    {
        if (bingt[fr][i] == -1 || v[bingt[fr][i]] > v[to])
        {
            continue;
        }

        ans += (1ll << i);
        fr = bingt[fr][i];
    }
    for (int i = LOG - 1; i > -1; i--)
    {
        if (binls[fr][i] == -1 || v[binls[fr][i]] > v[to])
        {
            continue;
        }

        ans += (1ll << i);
        fr = binls[fr][i];
    }
    return ans;
}

/*
int main()
{
    int N = 0, Q = 0;
    assert(2 == scanf("%d %d", &N, &Q));
    std::vector<int> H(N);
    for (int i = 0; i < N; ++i)
    {
        assert(1 == scanf("%d", &H[i]));
    }
    init(N, H);

    for (int i = 0; i < Q; ++i)
    {
        int A = 0, B = 0, C = 0, D = 0;
        assert(4 == scanf("%d %d %d %d", &A, &B, &C, &D));
        printf("%d\n", minimum_jumps(A, B, C, D));
    }
    return 0;
}
*/

/*
<3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3
⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠤⠖⠚⢉⣩⣭⡭⠛⠓⠲⠦⣄⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢀⡴⠋⠁⠀⠀⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⢦⡀⠀⠀⠀⠀
⠀⠀⠀⠀⢀⡴⠃⢀⡴⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣆⠀⠀⠀
⠀⠀⠀⠀⡾⠁⣠⠋⠀⠈⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⠀⠀
⠀⠀⠀⣸⠁⢰⠃⠀⠀⠀⠈⢣⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣇⠀
⠀⠀⠀⡇⠀⡾⡀⠀⠀⠀⠀⣀⣹⣆⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀
⠀⠀⢸⠃⢀⣇⡈⠀⠀⠀⠀⠀⠀⢀⡑⢄⡀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇
⠀⠀⢸⠀⢻⡟⡻⢶⡆⠀⠀⠀⠀⡼⠟⡳⢿⣦⡑⢄⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇
⠀⠀⣸⠀⢸⠃⡇⢀⠇⠀⠀⠀⠀⠀⡼⠀⠀⠈⣿⡗⠂⠀⠀⠀⠀⠀⠀⠀⢸⠁
⠀⠀⡏⠀⣼⠀⢳⠊⠀⠀⠀⠀⠀⠀⠱⣀⣀⠔⣸⠁⠀⠀⠀⠀⠀⠀⠀⢠⡟⠀
⠀⠀⡇⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀
⠀⢸⠃⠘⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠁⠀⠀⢀⠀⠀⠀⠀⠀⣾⠀⠀
⠀⣸⠀⠀⠹⡄⠀⠀⠈⠁⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠸⠀⠀⠀⠀⠀⡇⠀⠀
⠀⡏⠀⠀⠀⠙⣆⠀⠀⠀⠀⠀⠀⠀⢀⣠⢶⡇⠀⠀⢰⡀⠀⠀⠀⠀⠀⡇⠀⠀
⢰⠇⡄⠀⠀⠀⡿⢣⣀⣀⣀⡤⠴⡞⠉⠀⢸⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⣧⠀⠀
⣸⠀⡇⠀⠀⠀⠀⠀⠀⠉⠀⠀⠀⢹⠀⠀⢸⠀⠀⢀⣿⠇⠀⠀⠀⠁⠀⢸⠀⠀
⣿⠀⡇⠀⠀⠀⠀⠀⢀⡤⠤⠶⠶⠾⠤⠄⢸⠀⡀⠸⣿⣀⠀⠀⠀⠀⠀⠈⣇⠀
⡇⠀⡇⠀⠀⡀⠀⡴⠋⠀⠀⠀⠀⠀⠀⠀⠸⡌⣵⡀⢳⡇⠀⠀⠀⠀⠀⠀⢹⡀
⡇⠀⠇⠀⠀⡇⡸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠮⢧⣀⣻⢂⠀⠀⠀⠀⠀⠀⢧
⣇⠀⢠⠀⠀⢳⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡎⣆⠀⠀⠀⠀⠀⠘
⢻⠀⠈⠰⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠘⢮⣧⡀⠀⠀⠀⠀
⠸⡆⠀⠀⠇⣾⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠆⠀⠀⠀⠀⠀⠀⠀⠙⠳⣄⡀⢢⡀
<3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3 <3
*/

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

jumps.cpp: In constructor 'sparse_table::sparse_table(std::vector<int>&)':
jumps.cpp:53:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   53 |         for (int i = 1; i < t.size(); i++)
      |                         ~~^~~~~~~~~~
jumps.cpp:57:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   57 |             for (int j = 0; j < t[i].size(); j++)
      |                             ~~^~~~~~~~~~~~~
#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...