제출 #718452

#제출 시각아이디문제언어결과실행 시간메모리
718452aryan12Rainforest Jumps (APIO21_jumps)C++17
48 / 100
1331 ms36120 KiB
#include "jumps.h"
#include <bits/stdc++.h>
#include <vector>
using namespace std;
 
const int MAXN = 2e5 + 5;
int dp_min[19][MAXN], dp_max[19][MAXN];
int seg[MAXN * 4]; // at position i stores the value H[i]
vector<int> H, REV;
int N;
 
void Build(int left, int right, int pos)
{
    if(left == right)
    {
        seg[pos] = H[left];
        return;
    }
    int mid = (left + right) / 2;
    Build(left, mid, pos * 2);
    Build(mid + 1, right, pos * 2 + 1);
    seg[pos] = max(seg[pos * 2], seg[pos * 2 + 1]);
}
 
int Query(int l, int r, int pos, int ql, int qr)
{
    if(ql <= l && r <= qr)
    {
        return seg[pos];
    }
    if(ql > r || l > qr)
    {
        return -1;
    }
    int mid = (l + r) >> 1;
    return max(Query(l, mid, pos * 2, ql, qr), Query(mid + 1, r, pos * 2 + 1, ql, qr));
}
 
pair<int, int> Query(int l, int r, int pos, int ql, int qr, int qval)
{
    // first is the smallest accessible element
    // second is whether the range has become inaccessible or not?
    if(ql > r || l > qr)
    {
        // cout << "(" << l << ", " << r << ")  returns: {" << 0 << ", " << 0 << "}\n";
        return {-1, 0};
    }
    if(ql <= l && r <= qr && seg[pos] <= qval)
    {
        // cout << "(" << l << ", " << r << ")  returns: {" << seg[pos] << ", " << seg[pos] << "}\n";
        return {seg[pos], seg[pos]};
    }
    if(l == r && seg[pos] > qval)
    {
        // cout << "(" << l << ", " << r << ")  returns: {" << -1 << ", " << -1 << "}\n";
        return {-1, -1};
    }
    int mid = (l + r) / 2;
    pair<int, int> ans1 = Query(mid + 1, r, pos * 2 + 1, ql, qr, qval);
    if(ans1.second == -1)
    {
        // cout << "(" << l << ", " << r << ")  returns: {" << ans1.first << ", " << ans1.second << "}\n";
        return ans1;
    }
    pair<int, int> ans2 = Query(l, mid, pos * 2, ql, qr, qval);
    if(ans2.second == -1)
    {
        // cout << "(" << l << ", " << r << ")  returns: {" << max(ans1.first, ans2.first) << ", " << -1 << "}\n";
        return {max(ans1.first, ans2.first), -1};
    }
    // cout << "(" << l << ", " << r << ")  returns: {" << max(ans1.first, ans2.first) << ", " << max(ans1.second, ans2.second) << "}\n";
    return {max(ans1.first, ans2.first), max(ans1.second, ans2.second)};
}
 
void init(int n, std::vector<int> h) 
{
    stack<int> s;
    N = n;
    REV.resize(N + 1);
    for(int i = 0; i < h.size(); i++)
    {
        H.push_back(h[i]);
        REV[H[i]] = i;
    }
    Build(0, N - 1, 1);
    for(int i = 0; i < N; i++)
    {
        while(!s.empty() && H[s.top()] < H[i])
        {
            s.pop();
        }
        if(s.empty())
        {
            dp_min[0][i] = -1;
        }
        else
        {
            dp_min[0][i] = s.top();
        }
        s.push(i);
    }
    while(!s.empty())
    {
        s.pop();
    }
    for(int i = N - 1; i >= 0; i--)
    {
        while(!s.empty() && H[s.top()] < H[i])
        {
            s.pop();
        }
        if(s.empty())
        {
            dp_max[0][i] = -1;
        }
        else
        {
            dp_max[0][i] = s.top();
        }
        s.push(i);
        if(dp_min[0][i] == -1 || (dp_max[0][i] != -1 && H[dp_max[0][i]] < H[dp_min[0][i]]))
        {
            swap(dp_min[0][i], dp_max[0][i]);
        }
    }
    for(int i = 1; i < 19; i++)
    {
        for(int j = 0; j < N; j++)
        {
            dp_min[i][j] = (dp_min[i - 1][j] == -1) ? -1 : dp_min[i - 1][dp_min[i - 1][j]];
            dp_max[i][j] = (dp_max[i - 1][j] == -1) ? -1 : dp_max[i - 1][dp_max[i - 1][j]];
            assert(dp_max[i][j] == -1 || H[dp_max[i][j]] >= H[dp_min[i][j]]);
        }
    }
    // for(int i = 0; i < N; i++)
    // {
    //     for(int j = 0; j < 19; j++)
    //     {
    //         cout << "val: " << min_max_node[j][i] << ", " << max_max_node[j][i] << "\n";
    //         cout << "dp: " << dp_min[j][i] << ", " << dp_max[j][i] << "\n";
    //     }
    // }
}

int query(int l, int r, int pos, int ql, int qr, int qval)
{
    if(ql > r || l > qr || seg[pos] <= qval)
    {
        return -1;
    }
    if(l == r)
    {
        return l;
    }
    int mid = (l + r) >> 1;
    int ans1 = query(l, mid, pos * 2, ql, qr, qval);
    if(ans1 != -1)
    {
        return ans1;
    }
    return query(mid + 1, r, pos * 2 + 1, ql, qr, qval); 
}
 
int minimum_jumps(int A, int B, int C, int D) 
{
    // A = B && C = D
    // cout << "---- ---- ---- ---- ----\n";
    // cout << "A = " << A << ", B = " << B << "\n";
    int HIGHEST = Query(0, N - 1, 1, C, D);
    HIGHEST = REV[HIGHEST];
    // cout << "HIGHEST = " << HIGHEST << "\n";
    int query_result = Query(0, N - 1, 1, A, B, H[HIGHEST]).first;
    // cout << "query_result = " << query_result << "\n";
    if(query_result == -1)
    {
        return -1;
    }
    A = REV[query_result];
    B = A;
    // cout << "A = " << A << "\n";

    C = query(0, N - 1, 1, C, D, H[A]); // query for the smallest element >= H[A]
    // cout << "C = " << C << "\n";
    if(C == -1)
    {
        return -1;
    }
    // C = REV[C];
    D = C;
    // cout << "A = " << A << ", B = " << B << "\n";
    // cout << "---- ---- ---- ---- ----\n";
    int ans = 0;
    for(int i = 18; i >= 0; i--)
    {
        if(dp_max[i][A] != -1 && H[dp_max[i][A]] <= H[C])
        {
            ans += (1 << i);
            A = dp_max[i][A];
        }
    }
    // cout << "ans = " << ans << ", A = " << A << "\n";
    for(int i = 18; i >= 0; i--)
    {
        if(dp_min[i][A] != -1 && H[dp_min[i][A]] <= H[C])
        {
            ans += (1 << i);
            A = dp_min[i][A];
        }
    }
    // cout << "ans = " << ans << ", A = " << A << "\n";
    if(A == C)
    {
        return ans;
    }
    return -1;
}

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

jumps.cpp: In function 'void init(int, std::vector<int>)':
jumps.cpp:80:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   80 |     for(int i = 0; i < h.size(); 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...