タイトル説明
既存の\(N- \)線分、左右のエンドポイントの各セグメント\(L_iを、R_iを\)を確実にするために、\(L_iを\ルR_iを\)を。
そこ\(m個\)クエリ、各クエリ\(X_I、Y_I \)必要最小限のライン間隔により覆わすべての点。
入力
最初の行の入力は、2つの整数を含む\(N、M \) 、意味は上記に示しました。
次に、ある(N \)\行は、各行は2つの整数を有します。
最初の\(I + 1 \)ラインが含まれている\を(2 \)の整数、それぞれ、\(L_iを、R_iを\) 。
次\(m個\)ライン、示し\(m個\)質問THが。
\(1 \ nは、2E5の\ \ M)
(L_iを\ R_iと\ 5E5の\ \ 0)\
\(0 \ X_I \ Y_I \ 5E5 \)
出力
出力各照会のための答え。
あなたがカバーできない場合は、出力\(--1 \)することができます。
サンプル入力
2 3
1 3
2 4
1 3
1 4
3 4
3 4
1 3
1 3
4 5
1 2
1 3
1 4
1 5
サンプル出力
1
2
1
1
1
-1
-1
メンテナンスセグメント間隔をカバーするために乗算器を使用して。
まず、我々は唯一のエンドポイントのため、我々はどこへ行くカバーするケア・セグメント遠いとそれをカバーできることがわかりました。
各治療右点遠い同じセグメントと左端点について。
だから、プロセスは、最遠点をジャンプしてエンドポイントをカバーするために残っている\(ANS ++ \) 、右のポイントにカバーされるまで、このプロセスを繰り返します。
暴力的なシミュレーションであれば、別のエンドポイントへの1つのセグメントからそれぞれのジャンプ、時間の複雑\(O(N)\) 。
我々は、このプロセスを発見し、それについて考えてみよう\(LCA \)プロセスは、のようなので、我々は維持掛けることができます。
\(FA [I] [J ] \) で表される\(1 << J \)線分から\(Iは\)遠い点をカバーすることができる始まります。
コードは以下の通りです
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
#define u64 unsigned long long
#define Raed Read
#define reg register
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,G,x) for(reg int i=(G).Head[x]; i; i=(G).Nxt[i])
inline int Read() {
int res = 0, f = 1;
char c;
while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
do res = (res << 3) + (res << 1) + (c ^ 48);
while (c = getchar(), c >= 48 && c <= 57);
return f ? res : -res;
}
template<class T>inline bool Min(T &a, T const&b) {
return a > b ? a = b, 1 : 0;
}
template<class T>inline bool Max(T &a, T const&b) {
return a < b ? a = b, 1 : 0;
}
const int N = 2e5 + 5, M = 5e5 + 5, mod = 1e6 + 7;
const int dx[5] = {1, -1, 0, 0, 0}, dy[5] = {0, 0, 0, 1, -1};
const double eps = 1e-6;
int Fa[M][20], R[M];
inline void _main(void) {
int n = Read(), m = Raed();
rep(i, 1, n) {
int x = Raed(), y = Read();
Max(R[x], y);
}
Fa[0][0] = R[0];
rep(i, 1, M - 5)Max(R[i], R[i - 1]), Fa[i][0] = R[i];
rep(j, 1, 19)rep(i, 0, M - 5)Fa[i][j] = Fa[Fa[i][j - 1]][j - 1];
while (m--) {
int Ans = 0, l = Raed(), r = Raed();
drep(i, 19, 0)if (Fa[l][i] < r)l = Fa[l][i], Ans |= 1 << i;
l = Fa[l][0];
if (l < r)Ans = -1;
else Ans++;
printf("%d\n", Ans);
}
}
signed main() {
#define offline1
#ifdef offline
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
_main();
fclose(stdin); fclose(stdout);
#else
_main();
#endif
return 0;
}