一个很妙的操作,求出每个点通过一条边可以向右边覆盖的最远距离,然后倍增。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define R register
#define LL long long
const int inf = 0x3f3f3f3f;
const int MAXN = 5e5 + 10;
inline int read() {
char a = getchar(); int x = 0,f = 1;
for(; a > '9' || a < '0'; a = getchar()) if(a == '-') f = -1;
for(; a >= '0' && a <= '9' ;a = getchar()) x = x * 10 + a - '0';
return x * f;
}
int n, m, D;
int mx[MAXN];
int dp[MAXN][20];
int main() {
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n = read(); m = read();
for(R int i = 1; i <= n; i++) {
int x = read(), y = read();
mx[x] = max(mx[x], y);
D = max(D, y);
}
for(R int i = 1; i <= D; i++) mx[i] = max(mx[i], mx[i - 1]);
//for(R int i = 1; i <= D; i++) printf("%d ", mx[i]);
for(R int i = 0; i <= D; i++) dp[i][0] = mx[i];
for(R int j = 1; j < 20; j++)
for(R int i = 0; i <= D; i++)
dp[i][j] = dp[dp[i][j - 1]][j - 1];
while(m--) {
int l = read(), r = read();
int ans = 0;
for(R int i = 19 ; i >= 0 ; i --)
if(dp[l][i] < r) {
ans += (1 << i);
l = dp[l][i];
}
if(mx[l] >= r) printf("%d\n", ans + 1);
else printf("-1\n");
}
return 0;
}