1 条题解

  • 0
    @ 2026-5-3 18:01:06

    暴力就是直接建出图来,跑最短路。

    可以用线段树优化建图,但没有前途。

    从前往后肯定不行,因为太多选择。

    正难则反,反着来贪心发现 ll 越小越好。

    这个可以用线段树来求。

    接着,每一个点都只有一个选择,即一个父亲,所以变成了树。

    然后,图就变成了树,然后树上倍增就可以求了。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <bitset>
    #include <cstring>
    #include <cmath>
    #include <random>
    #include <cstdlib>
    #include <cassert>
    #include <vector>
    #include <iomanip>
    #include <unordered_map>
    #include <set>
    // #include <ext/pb_ds/assoc_container.hpp>
    // using namespace __gnu_pbds;
    #define ll long long
    #define ull unsigned long long
    #define REP(i, l, r) for(int i = l; i <= r; ++i)
    #define PER(i, r, l) for(int i = r; i >= l; --i)
    using namespace std;
    
    template<typename T>void chkmin(T &x, T y) {if(x>y) x=y;}
    template<typename T>void chkmax(T &x, T y) {if(x<y) x=y;}
    
    namespace Main {
    
    const int N = 200000 + 5;
    int n, Q;
    struct node {
    	int l, r;
    } a[N];
    int tot;
    int b[N];
    int lg[N];
    int minn[20][N];
    int nxt[N][20];
    int QwQ(int l,int r) {
    	return a[l].l < a[r].l ? l : r;
    }
    int rmq(int l,int r) {
    	int k = lg[r - l + 1];
    	return QwQ(minn[k][l], minn[k][r-(1<<k)+1]);
    }
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0), cout.tie(0);
    	cin >> n >> Q;
    	REP(i, 2, 2 * n) lg[i] = lg[i >> 1] + 1;
    	REP(i, 1, n) {
    		cin >> a[i].l >> a[i].r;
    		b[++tot] = a[i].l, b[++tot] = a[i].r;
    	}
    	sort(b + 1, b + 1 + tot);
    	tot = unique(b + 1, b + 1 + tot) - b - 1;
    	REP(i, 1, n) {
    		a[i].l = lower_bound(b + 1, b + 1 + tot, a[i].l) - b;
    		a[i].r = lower_bound(b + 1, b + 1 + tot, a[i].r) - b;
    	}
    	a[0].l = 2e9;
    	// memset(minn, 0x3f, sizeof(minn));
    	REP(i, 1, n)
    		minn[0][a[i].r] = QwQ(minn[0][a[i].r], i);
    	REP(i, 1, lg[tot]) {
    		for(int j = 1; j + (1 << i) - 1 <= tot; ++j) {
    			minn[i][j] = QwQ(minn[i - 1][j], minn[i - 1][j + (1 << (i - 1))]);
    		}
    	}
    	REP(i, 1, n) nxt[i][0] = rmq(a[i].l, a[i].r);
    	REP(j, 1, lg[2 * n]) {
    		for(int i = 1; i <= n; ++i) nxt[i][j] = nxt[nxt[i][j - 1]][j - 1];
    	}
    	REP(i, 1, Q) {
    		int t, s;
    		cin >> t >> s;
    		int ans = 2;
    		if(a[s].r<a[t].r) {
    			cout<<"impossible\n";
    		}
    		else if(s==t) {
    			cout<<0<<'\n';
    		}
    		else if(a[s].l<=a[t].r) {
    			cout<<1<<'\n';
    		}
    		else {
    			for(int i = lg[2*n]; i>=0; --i) {
    				if(a[nxt[s][i]].l > a[t].r) s=nxt[s][i], ans+=(1<<i);
    			}
    			if(ans>n) cout<<"impossible\n";
    			else cout<<ans<<'\n';
    		}
    	}
    	return 0;
    }
    
    }
    int main() {
    	Main :: main();
    	return 0;
    }
    
    • 1

    信息

    ID
    7269
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    5
    已通过
    1
    上传者