Submission #1161684

#TimeUsernameProblemLanguageResultExecution timeMemory
1161684HanksburgerEvent Hopping (BOI22_events)C++20
100 / 100
998 ms46644 KiB
#include <bits/stdc++.h>
using namespace std;
int largestRangeInd[100005], reachable[100005][20], seg[400005][20], n, q, cnt;
vector<pair<int, int> > endpointsSet[100005];
vector<pair<pair<int, int>, int> > Ranges;
pair<int, int> position[100005];
map<int, int> endpointsMap;
set<int> endpoints;
void build(int ind, int i, int l, int r)
{
    if (l==r)
    {
        seg[i][ind]=reachable[l][ind];
        return;
    }
    int mid=(l+r)/2;
    build(ind, i*2, l, mid);
    build(ind, i*2+1, mid+1, r);
    seg[i][ind]=max(seg[i*2][ind], seg[i*2+1][ind]);
}
int query(int ind, int i, int l, int r, int ql, int qr)
{
    if (ql<=l && r<=qr)
        return seg[i][ind];
    int mid=(l+r)/2, result=0;
    if (ql<=mid && l<=qr)
        result=max(result, query(ind, i*2, l, mid, ql, qr));
    if (ql<=r && mid<qr)
        result=max(result, query(ind, i*2+1, mid+1, r, ql, qr));
    return result;
}
int findDistance(int L, int R, int target)
{
    //cout << "findDistance " << L << ' ' << R << ' ' << target << '\n';
    if (L>R || query(18, 1, 1, cnt, L, R)<target)
        return 1e9;
    if (L<=target && target<=R)
        return 0;
    int ans=0;
    for (int i=18; i>=0; i--)
    {
        int res=query(i, 1, 1, cnt, L, R);
        if (res<target)
        {
            ans+=(1<<i);
            R=res;
        }
    }
    return ans+1;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> q;
    for (int i=1; i<=n; i++)
    {
        int l, r;
        cin >> l >> r;
        Ranges.push_back({{l, r}, i});
        endpoints.insert(r);
        endpointsMap[r]=0;
    }
    for (int i=0; i<n; i++)
    {
        int l=Ranges[i].first.first;
        Ranges[i].first.first=*endpoints.lower_bound(l);
    }
    cnt=endpointsMap.size();
    for (auto it=endpointsMap.begin(); it!=endpointsMap.end(); it++)
    {
        (it->second)=cnt;
        cnt--;
    }
    for (int i=0; i<n; i++)
    {
        Ranges[i].first={endpointsMap[Ranges[i].first.first], endpointsMap[Ranges[i].first.second]};
        endpointsSet[Ranges[i].first.second].push_back({Ranges[i].first.first, Ranges[i].second});
    }
    cnt=endpointsMap.size();
    for (int i=1; i<=cnt; i++)
    {
        for (int j=1; j<endpointsSet[i].size(); j++)
            if (endpointsSet[i][largestRangeInd[i]].first<endpointsSet[i][j].first)
                largestRangeInd[i]=j;
        reachable[i][0]=endpointsSet[i][largestRangeInd[i]].first;
    }
    for (int i=1; i<20; i++)
    {
        build(i-1, 1, 1, cnt);
        for (int j=1; j<=cnt; j++)
            reachable[j][i]=query(i-1, 1, 1, cnt, j, reachable[j][i-1]);
    }
    for (int i=1; i<=cnt; i++)
        for (int j=0; j<endpointsSet[i].size(); j++)
            position[endpointsSet[i][j].second]={i, endpointsSet[i][j].first};
    /*cout << "Ranges:\n";
    for (int i=0; i<n; i++)
        cout << Ranges[i].first.first << ' ' << Ranges[i].first.second << '\n';
    cout << "endpointsSets:\n";
    for (int i=1; i<=cnt; i++)
    {
        cout << "Set " << i << ": ";
        for (auto x:endpointsSet[i])
            cout << x.first << ' ';
        cout << '\n';
    }
    cout << "positions:\n";
    for (int i=1; i<=n; i++)
        cout << position[i].first << ' ' << position[i].second << '\n';*/
    for (int i=1; i<=q; i++)
    {
        int startIndex, endIndex;
        cin >> endIndex >> startIndex;
        if (position[startIndex].first>position[endIndex].first)
        {
            cout << "impossible\n";
            continue;
        }
        if (position[startIndex].first==position[endIndex].first)
        {
            if (startIndex==endIndex)
                cout << 0 << '\n';
            else
                cout << 1 << '\n';
            continue;
        }
        int L=position[startIndex].first, R=position[startIndex].second, target=position[endIndex].first;
        int ans=min(findDistance(L+1, R, target), findDistance(L, L, target))+1;
        if (ans>1e9)
            cout << "impossible\n";
        else
            cout << ans << '\n';
    }
}
#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...