1 条题解
-
0
暴力就是直接建出图来,跑最短路。
可以用线段树优化建图,但没有前途。
从前往后肯定不行,因为太多选择。
正难则反,反着来贪心发现 越小越好。
这个可以用线段树来求。
接着,每一个点都只有一个选择,即一个父亲,所以变成了树。
然后,图就变成了树,然后树上倍增就可以求了。
#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
- 上传者