一个很妙的操作,求出每个点通过一条边可以向右边覆盖的最远距离,然后倍增。

#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;	
}