Flying Squirrel --- Gym - 102091A(RMQ + 思维)
题目
https://vjudge.net/problem/Gym-102091A
题意
从左到右给出 n 个位置固定机场和 m 个询问,每个机场有自己的高度 H,每个飞机只能向高度比原高度小的地方飞,并且途中不能经过大于等于原高度的位置。询问给出两个参数 u,v。
当 v ! = 0 时,从 u,v 中较高处向较低出飞,最多途径几个机场(包括终点)飞到终点。
当 v == 0 时,从 u 起飞,不固定终点,问最多途径几个机场(包括终点)飞到终点。
题解
对于每个机场,若是想要飞的多,肯定是要飞到能去往终点并且最高的地方,所以我们其实按照树结构的思想,对每个点进行深度分层,那么对于两个点的结果也就是他们的深度差。如果有多个同一高度的机场可以飞但是不知道该去哪个,其实并不用考虑这个问题,题目并不要求我们输出路径,所以可以当作飞机一定会飞往可以到达目标点的那个最高处即可。那么对于区间最大值的查询可以需处理出 ST 表。然后 dfs 区间处理当前区间最高几个机场的深度即可。
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define ull unsigned long long 4 #define met(a, b) memset(a, b, sizeof(a)) 5 #define rep(i, a, b) for(int i = a; i <= b; i++) 6 #define bep(i, a, b) for(int i = a; i >= b; i--) 7 #define lowbit(x) (x&(-x)) 8 #define MID (l + r) / 2 9 #define ls pos*2 10 #define rs pos*2+1 11 #define pb push_back 12 #define ios() ios::sync_with_stdio(0) 13 14 using namespace std; 15 16 const int maxn = 1e6 + 1010; 17 const int inf = 0x3f3f3f3f; 18 const ll INF = 0x3f3f3f3f3f3f3f3f; 19 const ll mod = 123456789; 20 21 int L[maxn], R[maxn]; 22 int arr[maxn], st[maxn][21]; 23 int depst[maxn][21]; 24 int n, m; 25 int deep[maxn]; 26 27 int st_query(int l, int r) { 28 int k = log2(r - l + 1); 29 if(arr[st[l][k]] >= arr[st[r - (1 << k) + 1][k]]) return st[l][k]; 30 else return st[r - (1 << k) + 1][k]; 31 } 32 int depst_query(int l, int r) { 33 int k = log2(r - l + 1); 34 return max(depst[l][k], depst[r - (1 << k) + 1][k]); 35 } 36 void dfs(int l, int r, int dep) { 37 // cout << l << ' ' << r << endl; int a; cin >> a; 38 if(l > r) return; 39 int now = st_query(l, r); 40 deep[now] = dep; 41 if(l == r) return; 42 dfs(l, now - 1, dep + 1); 43 l = now; 44 while(l < r && arr[st_query(l + 1, r)] == arr[now]) { 45 int t = st_query(l + 1, r); 46 // cout << l << ' ' << t << endl; int a; cin >> a; 47 deep[t] = dep; 48 dfs(l + 1, t - 1, dep + 1); 49 l = t; 50 } 51 dfs(l + 1, r, dep + 1); 52 } 53 54 int main() { 55 cin >> n >> m; 56 rep(i, 1, n) { 57 cin >> arr[i]; 58 st[i][0] = i; 59 } 60 rep(j, 1, 20) { 61 int i = 1; 62 while(i + (1 << j) - 1 <= n) { 63 if(arr[st[i][j-1]] >= arr[st[i + (1 << (j-1))][j-1]]) st[i][j] = st[i][j-1]; 64 else st[i][j] = st[i + (1 << (j-1))][j-1]; 65 i++; 66 } 67 } 68 L[0] = 0; 69 rep(i, 1, n) { 70 int t = i - 1; 71 while(t && arr[t] < arr[i]) t = L[t]; 72 L[i] = t; 73 } 74 R[n+1] = n+1; 75 bep(i, n, 1) { 76 int t = i + 1; 77 while(t <= n && arr[t] < arr[i]) t = R[t]; 78 R[i] = t; 79 } 80 dfs(1, n, 1); 81 rep(i, 1, n) depst[i][0] = deep[i]; 82 83 rep(j, 1, 20) { 84 int i = 1; 85 while(i + (1 << j) - 1 <= n) { 86 depst[i][j] = max(depst[i][j-1], depst[i + (1 << (j-1))][j-1]); 87 i++; 88 } 89 } 90 rep(i, 1, m) { 91 int l, r; 92 cin >> l >> r; 93 if(r == 0) cout << depst_query(L[l] + 1, R[l] - 1) - deep[l] << endl; 94 else { 95 if(l > r) swap(l, r); 96 if(l == r || (r - l == 1 && arr[l] == arr[r])) { 97 cout << 0 << endl; 98 continue; 99 } 100 if(r - l > 1 && arr[st_query(l + 1, r - 1)] >= max(arr[l], arr[r])) { 101 cout << 0 << endl; 102 continue; 103 } 104 cout << abs(deep[l] - deep[r]) << endl; 105 } 106 } 107 return 0; 108 }