Submission #1183351

#TimeUsernameProblemLanguageResultExecution timeMemory
1183351jerzykRailway Trip 2 (JOI22_ho_t4)C++20
100 / 100
443 ms90872 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
using namespace __gnu_pbds;
using namespace std;
#define pb push_back
#define st first
#define nd second
typedef long long ll;
typedef long double ld;
const ll I = 1000'000'000'000'000'000LL;
const int II = 2'000'000'000;
const ll M = 1000'000'007LL;
const int K = 18;
const int N = 1<<K;
int l[N], r[N];
int jp[2][K][N];
int drz[2][K][2 * N];
vector<int> beg[N], en[N];
multiset<int> aktt;

void Build(int p, int k)
{
    for(int v = N - 1; v >= 1; --v)
        drz[p][k][v] = max(drz[p][k][v * 2], drz[p][k][v * 2 + 1]);
}

int Query(int p, int k, int a, int b)
{
    a += N - 1; b += N + 1;
    int ans = -II;
    while(a / 2 != b / 2)
    {
        if(a % 2 == 0) ans = max(ans, drz[p][k][a + 1]);
        if(b % 2 == 1) ans = max(ans, drz[p][k][b - 1]);
        a /= 2; b /= 2;
    }
    if(p == 0) return -ans;
    return ans;
}

void LiczJP(int n)
{
    for(int i = 1; i <= n; ++i)
    {
        jp[0][0][i] = l[i]; jp[1][0][i] = r[i];
        drz[0][0][i + N] = -jp[0][0][i];
        drz[1][0][i + N] = jp[1][0][i];
    }
    Build(0, 0);
    Build(1, 0);
    for(int j = 1; j < K; ++j)
    {
        for(int i = 1; i <= n; ++i)
        {
            int a = jp[0][j - 1][i], b = jp[1][j - 1][i];
            jp[0][j][i] = Query(0, j - 1, a, b);
            jp[1][j][i] = Query(1, j - 1, a, b);
            drz[0][j][i + N] = -jp[0][j][i];
            drz[1][j][i + N] = jp[1][j][i];
        }
        Build(0, j);
        Build(1, j);
    }
}

int Jump(int a, int t)
{
    int b = a, ans = 0;
    for(int j = K - 1; j >= 0; --j)
    {
        int na = Query(0, j, a, b), nb = Query(1, j, a, b);
        if(!(na <= t && nb >= t))
        {
            ans += (1<<j);
            a = na; b = nb;
        }
    }
    if(ans == (1<<K) - 1) return -1;
    if(a <= t && b >= t) return ans;
    return ans + 1;
}

void Solve()
{
    int n, m, k, q, a, b;
    cin >> n >> k;
    cin >> m;
    for(int i = 1; i <= m; ++i)
    {
        cin >> a >> b;
        if(a <= b)
        {
            beg[a].pb(b);
            en[min(b + 1, a + k)].pb(b);
        }else
        {
            swap(a, b);
            beg[max(a, b - k + 1)].pb(a);
            en[b + 1].pb(a);
        }
    }
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 0; j < (int)beg[i].size(); ++j) aktt.insert(beg[i][j]);
        for(int j = 0; j < (int)en[i].size(); ++j) aktt.erase(aktt.find(en[i][j]));
        l[i] = i; r[i] = i;
        if((int)aktt.size() > 0)
            {l[i] = *aktt.begin(); r[i] = *aktt.rbegin();}
        l[i] = min(l[i], i); r[i] = max(r[i], i);
    }
    LiczJP(n);
    cin >> q;
    for(int i = 1; i <= q; ++i)
    {
        cin >> a >> b;
        int ans = Jump(a, b);
        cout << ans << "\n";
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    //int t; cin >> t;
    //while(t--)
        Solve();

    return 0;
}
#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...