제출 #1013508

#제출 시각아이디문제언어결과실행 시간메모리
1013508boris_mihov밀림 점프 (APIO21_jumps)C++17
4 / 100
817 ms62032 KiB
#include "jumps.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <stack>
 
typedef long long llong;
const int MAXN = 200000 + 10;
const int MAXLOG = 20;
const llong INF = 1e18;
const int INTINF = 2e9;
 
int n;
int h[MAXN];
int firstR[MAXN];
int firstL[MAXN];
std::stack <int> st;
 
struct SparseRMQ
{
    int sparse[MAXLOG][MAXN];
    int getLOG[MAXN];
 
    void build()
    {
        for (int i = 1 ; i <= n ; ++i)
        {
            sparse[0][i] = h[i];
        }
 
        for (int log = 1 ; (1 << log) <= n ; ++log)
        {
            for (int i = 1 ; i + (1 << log) - 1 <= n ; ++i)
            {
                sparse[log][i] = std::max(sparse[log - 1][i], sparse[log - 1][i + (1 << log - 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 log = getLOG[r - l + 1];
        return std::max(sparse[log][l], sparse[log][r - (1 << log) + 1]);
    }
};
 
SparseRMQ sparseMAX;
struct SparseLCA
{
    int sparse[MAXLOG][MAXN];
    void build(int p[])
    {
        for (int i = 1 ; i <= n ; ++i)
        {
            sparse[0][i] = p[i];
        }
 
        for (int log = 1 ; (1 << log) <= n ; ++log)
        {
            for (int i = 1 ; i <= n ; ++i)
            {
                sparse[log][i] = sparse[log - 1][sparse[log - 1][i]];
            }
        }
    }
 
    int kth(int log, int node)
    {
        return sparse[log][node];
    }
};
 
SparseLCA sparseL;
SparseLCA sparseR;
SparseLCA sparseLR;
int par[MAXN];
 
void init(int N, std::vector <int> H) 
{
    n = N;
    for (int i = 0 ; i < n ; ++i)
    {
        h[i + 1] = H[i];
    }
 
    h[0] = h[n + 1] = INTINF;
    st.push(0);
 
    for (int i = 1 ; i <= n ; ++i)
    {
        while (h[i] > h[st.top()])
        {
            st.pop();
        }
 
        firstL[i] = st.top();
        st.push(i);
    }
 
    while (st.size()) st.pop();
    st.push(n + 1);
 
    for (int i = n ; i >= 1 ; --i)
    {
        while (h[i] > h[st.top()])
        {
            st.pop();
        }
 
        firstR[i] = st.top();
        st.push(i);
    }
 
    firstR[0] = firstR[n + 1] = n + 1;
    for (int i = 1 ; i <= n ; ++i)
    {
        par[i] = firstL[i];
        if (h[firstR[i]] > h[par[i]]) par[i] = firstR[i];
    }
 
    sparseMAX.build();
    sparseL.build(firstL);
    sparseR.build(firstR);
    sparseLR.build(par);
}
 
int minimum_jumps(int a, int b, int c, int d) 
{
    a++; b++; c++; d++;
 
    int maxC = sparseMAX.findMAX(c, d);
    if (sparseMAX.findMAX(b, c - 1) > maxC)
    {
        return -1;
    }
 
    int node = b;
    for (int log = MAXLOG - 1 ; log >= 0 ; --log)
    {
        if (sparseL.kth(log, node) >= a && h[sparseL.kth(log, node)] <= maxC)
        {
            node = sparseL.kth(log, node);
        }
    }
 
    if (firstR[node] >= c)
    {
        return 1;
    }
 
    int res = 0;
    for (int log = MAXLOG - 1 ; log >= 0 ; --log)
    {
        if (h[sparseR.kth(log, node)] <= maxC && firstR[sparseR.kth(log, node)] < c)
        {
            res += (1 << log);
            node = sparseR.kth(log, node);
        }
    }
 
    assert(firstR[node] < c);
    if (h[sparseR.kth(0, node)] <= maxC)
    {
        assert(firstR[sparseR.kth(0, node)] >= c);
        node = sparseR.kth(0, node);
        node = sparseR.kth(0, node);
        assert(c <= node && node <= d);
        res += 2;
 
        return res;
    }
 
    assert(h[firstR[node]] <= maxC);
    for (int log = MAXLOG - 1 ; log >= 0 ; --log)
    {
        if (firstR[sparseR.kth(log, node)] < c)
        {
            res += (1 << log);
            node = sparseR.kth(log, node);
        }
    }
 
    assert(firstR[node] < c);
    node = firstR[node];
    assert(firstR[node] <= d);
    node = firstR[node];
    res += 2;
 
    assert(c <= node && node <= d);
    return res;
}

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

jumps.cpp: In member function 'void SparseRMQ::build()':
jumps.cpp:37:93: warning: suggest parentheses around '-' inside '<<' [-Wparentheses]
   37 |                 sparse[log][i] = std::max(sparse[log - 1][i], sparse[log - 1][i + (1 << log - 1)]);
      |                                                                                         ~~~~^~~
jumps.cpp:44:33: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
   44 |             if ((1 << getLOG[i] + 1) < i) getLOG[i]++;
      |                       ~~~~~~~~~~^~~
#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...