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 }
posted @ 2020-01-13 21:00  Ruby·Z  阅读(177)  评论(0编辑  收藏  举报