#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
int M = 100'000;
vector<pair<int, int>> seg(M);
int base = 1<<19;
vector<int> T(2*base, -1);
int zmaksuj(int a, int b) {
if(a==-1) return b;
if(b==-1) return a;
if(seg[a].second < seg[b].second) return b;
return a;
}
void update(int a, int b, int val) {
if(a>b) return;
if(a==b) T[a+base] = zmaksuj(T[a+base], val);
a+=base-1;
b+=base+1;
while(a/2!=b/2) {
if(a%2==0) T[a+1] = zmaksuj(T[a+1], val);
if(b%2==1) T[b-1] = zmaksuj(T[b-1], val);
a/=2; b/=2;
}
}
int query(int x) {
x += base;
ll ans = -1;
while(x>0) {
ans = zmaksuj(ans, T[x]);
x/=2;
}
return ans;
}
void parse_input(int n) {
map<int, vector<int>> konce;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, q;
cin >> n >> q;
ll inf = 1e9;
int maxlog = 16;
vector<vector<int>> jump(n, vector<int>(maxlog+1));
vector<int> XY;
for(int i=0; i<n; ++i) {
cin >> seg[i].first >> seg[i].second;
}
parse_input(n);
for(int i=0; i<n; ++i) {
XY.push_back(seg[i].first);
XY.push_back(seg[i].second);
}
sort(XY.begin(), XY.end());
for(int i=0; i<n; ++i) {
update(lower_bound(XY.begin(), XY.end(), seg[i].first) - XY.begin(), lower_bound(XY.begin(), XY.end(), seg[i].second) - XY.begin(), i);
// update(seg[i].first, seg[i].second, i);
}
for(int i=0; i<n; ++i) {
jump[i][0] = query(lower_bound(XY.begin(), XY.end(), seg[i].second) - XY.begin());
// cout << i << ": " << jump[i][0] << "\n";
// jump[i][0] = query(seg[i].second);
}
for(int j=1; j<=maxlog; ++j) {
for(int i=0; i<n; ++i) {
jump[i][j] = jump[jump[i][j-1]][j-1];
}
}
while(q--) {
int a, b;
cin >> a >> b;
--a;--b;
if(a==b) {
cout << "0\n";
continue;
}
int res = 0;
for(int i=maxlog; i>=0; --i) {
// if(i>0 && jump[a][i]==jump[a][i-1]) continue;
if(seg[jump[a][i]].second < seg[b].second) {
res += 1<<i;
a = jump[a][i];
}
}
// cout << a << " " << res << " - " << jump[a][0] << "\n";
if(seg[b].first <= seg[a].second && seg[a].second <= seg[b].second) cout << res+1 << "\n";
else {
bool ok = 0;
for(int i=0; i<n; ++i) if(seg[a].first <= seg[i].first && seg[i].first <= seg[a].second && seg[b].first <= seg[i].second && seg[i].second <= seg[b].second) {
cout << res+2 << '\n';
ok = 1;
break;
}
if(!ok) cout << "impossible\n";
}
}
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |