嗯嗯嗯。。 打倍增的时候两个for写反了查了半天bug。。。
我们先把没用的线段去掉, 然后对每个线段都找到和它接触的r最大的作为下一个, 然后打倍增就好了。
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 5e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} int n, m, c[N]; int prefix[N]; int nex[N][20]; struct Line { int l, r; bool operator < (const Line &rhs) const { if(l == rhs.l) return r > rhs.r; return l < rhs.l; } } a[N]; int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].l, &a[i].r), a[i].r--; sort(a + 1, a + 1 + n); int nn = n; n = 1; for(int i = 2; i <= nn; i++) if(a[i].r > a[n].r) a[++n] = a[i]; for(int i = 1; i <= n; i++) { c[a[i].l]++; c[a[i].r + 1]--; } if(!c[0]) prefix[0] = 1; for(int i = 1; i <= 500000; i++) { c[i] += c[i - 1]; if(!c[i]) prefix[i] = 1; prefix[i] += prefix[i - 1]; } for(int i = 1, j = 2; i <= n; i++) { j = max(i + 1, j); while(j <= n && a[j].l <= a[i].r + 1) j++; nex[i][0] = j - 1 == i ? 0 : j - 1; } for(int j = 1; j < 20; j++) for(int i = 1; i <= n; i++) nex[i][j] = nex[nex[i][j - 1]][j - 1]; while(m--) { int x, y; scanf("%d%d", &x, &y); y--; int cnt = prefix[y]; if(x) cnt -= prefix[x - 1]; if(cnt) { puts("-1"); } else { int p = lower_bound(a + 1, a + 1 + n, Line{x + 1, inf}) - a - 1; if(a[p].r >= y) { puts("1"); } else { int ans = 0; for(int i = 19; i >= 0; i--) { if(nex[p][i] && a[nex[p][i]].r < y) { p = nex[p][i], ans += (1 << i); } } printf("%d ", ans + 2); } } } return 0; }