Submission #864269

#TimeUsernameProblemLanguageResultExecution timeMemory
864269danikoynovEvent Hopping (BOI22_events)C++14
40 / 100
1589 ms9396 KiB
#include<bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 10;
     
struct interval
{
    int s, e, idx;
}seg[maxn];
     
struct query
{
    int start, finish, idx;
}task[maxn];

bool cmp_finish(query q1, query q2)
{
    return q1.finish < q2.finish;
}
int n, q;   


void input()
{
    cin >> n >> q;
    for (int i = 1; i <= n; i ++)
    {
        cin >> seg[i].s >> seg[i].e;
        seg[i].idx = i;
    }
    for (int i = 1; i <= q; i ++)
    {
        cin >> task[i].start >> task[i].finish;
        task[i].idx = i;
    }
}



bool cmp_end(interval seg1, interval seg2)
{
    return seg1.e < seg2.e;
}

int lf[maxn], rev[maxn], rf[maxn], ans[maxn];
map < int, int > fix;
void build_graph()
{
    sort(seg + 1, seg + n + 1, cmp_end);
    for (int i = 1; i <= n; i ++)
    {
        rev[seg[i].idx] = i;
    }

    for (int i = 1; i <= n; i ++)
    {
        int l = 1;
        int r = i;
        while(l <= r)
        {
            int m = (l + r) / 2;
            if (seg[m].e < seg[i].s)
                l = m + 1;
            else
                r = m - 1;
        }
        lf[i] = l;
        //while(seg[lf[i]].e < seg[i].s)
           // lf[i] ++;


        if (fix[seg[i].e] == 0)
            fix[seg[i].e] = lf[i];
        else
            fix[seg[i].e] = min(fix[seg[i].e], lf[i]);
    }
}

void answer_queries()
{
    for (int i = 1; i <= q; i ++)
    {
        task[i].start = rev[task[i].start];
        task[i].finish = rev[task[i].finish];
    }
    sort(task + 1, task + q + 1, cmp_finish);
    /**cout << "----------------------" << endl;
    for (int i = 1; i <= n; i ++)
        cout << seg[i].s << " :: " << seg[i].e << endl;*/
    vector < int > viable;
    for (int i = 1; i <= n; i ++)
    {

    }

    int pt = 1;
    for (int i = 1; i <= q; i ++)
    {

        int st = task[i].start, en = task[i].finish;

        while(pt <= en)
        {
            
            while(!viable.empty() && lf[viable.back()] >= lf[pt])
                viable.pop_back();
            viable.push_back(pt);
            pt ++;
        }
    if (st == en)
        {
            ans[task[i].idx] = 0;
            continue;
        }
        if (seg[st].e == seg[en].e && st != en)
        {
            ans[task[i].idx] = 1;
            continue;
        }
        
        if (st > en)
        {
            ans[task[i].idx] = -1;
            continue;
        }

        if (st >= lf[en])
        {
            ans[task[i].idx] = 1;
            continue;
        }

        
    
        int to = fix[seg[en].e];
        for (int i = lf[en]; i <= en; i ++)
            to = min(to, lf[i]);
        int steps = 1;

        bool done = false;
        int cur = viable.size() - 1;
        while(to > st)
        {
            while(cur >= 0 && viable[cur] >= to)
                cur --;
            cur ++;
            if (lf[viable[cur]] >= to)
            {
                done = true;
                break;
            }

            steps ++;
            to = lf[viable[cur]];
        }

        if (done == true)
        {
            ans[task[i].idx] = -1;
        }
        else
        {
           ans[task[i].idx] = steps + 1;
        }
    }

    for (int i = 1; i <= q; i ++)
    {
        if (ans[i] != - 1)
            cout << ans[i] << endl;
        else
            cout << "impossible" << endl;
    }
}
void solve()
{  
    input();
    build_graph();
    answer_queries();
}

int main()
{   
    ///speed();
    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...