# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1161682 | Hanksburger | Event Hopping (BOI22_events) | C++20 | 0 ms | 0 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;
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';
}
}