码迷,mamicode.com
首页 > 其他好文 > 详细

Flying Squirrel --- Gym - 102091A(RMQ + 思维)

时间:2020-01-13 21:53:09      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:参数   mem   要求   问题   题目   color   https   swap   inf   

题目

  https://vjudge.net/problem/Gym-102091A

题意

  从左到右给出 n 个位置固定机场和 m 个询问,每个机场有自己的高度 H,每个飞机只能向高度比原高度小的地方飞,并且途中不能经过大于等于原高度的位置。询问给出两个参数 u,v。

  当 v ! = 0 时,从 u,v 中较高处向较低出飞,最多途径几个机场(包括终点)飞到终点。

  当 v == 0 时,从 u 起飞,不固定终点,问最多途径几个机场(包括终点)飞到终点。

题解

  对于每个机场,若是想要飞的多,肯定是要飞到能去往终点并且最高的地方,所以我们其实按照树结构的思想,对每个点进行深度分层,那么对于两个点的结果也就是他们的深度差。如果有多个同一高度的机场可以飞但是不知道该去哪个,其实并不用考虑这个问题,题目并不要求我们输出路径,所以可以当作飞机一定会飞往可以到达目标点的那个最高处即可。那么对于区间最大值的查询可以需处理出 ST 表。然后 dfs 区间处理当前区间最高几个机场的深度即可。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define bep(i, a, b) for(int i = a; i >= b; i--)
#define lowbit(x) (x&(-x))
#define MID (l + r) / 2
#define ls pos*2
#define rs pos*2+1
#define pb push_back
#define ios() ios::sync_with_stdio(0)

using namespace std;

const int maxn = 1e6 + 1010;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 123456789;

int L[maxn], R[maxn];
int arr[maxn], st[maxn][21];
int depst[maxn][21];
int n, m;
int deep[maxn];

int st_query(int l, int r) {
    int k = log2(r - l + 1);
    if(arr[st[l][k]] >= arr[st[r - (1 << k) + 1][k]]) return st[l][k];
    else return st[r - (1 << k) + 1][k];
}
int depst_query(int l, int r) {
    int k = log2(r - l + 1);
    return max(depst[l][k], depst[r - (1 << k) + 1][k]);
}
void dfs(int l, int r, int dep) {
    // cout << l << ‘ ‘ << r << endl; int a; cin >> a;
    if(l > r) return;
    int now = st_query(l, r); 
    deep[now] = dep;
    if(l == r) return;
    dfs(l, now - 1, dep + 1);
    l = now;
    while(l < r && arr[st_query(l + 1, r)] == arr[now]) {
        int t = st_query(l + 1, r);
        // cout << l << ‘ ‘ << t << endl; int a; cin >> a;
        deep[t] = dep;
        dfs(l + 1, t - 1, dep + 1);
        l = t;
    }
    dfs(l + 1, r, dep + 1);
}

int main() {
    cin >> n >> m;
    rep(i, 1, n) {
        cin >> arr[i];
        st[i][0] = i;
    }
    rep(j, 1, 20) {
        int i = 1;
        while(i + (1 << j) - 1 <= n) {
            if(arr[st[i][j-1]] >= arr[st[i + (1 << (j-1))][j-1]]) st[i][j] = st[i][j-1];
            else st[i][j] = st[i + (1 << (j-1))][j-1];
            i++;
        }
    }
    L[0] = 0;
    rep(i, 1, n) {
        int t = i - 1;
        while(t && arr[t] < arr[i]) t = L[t];
        L[i] = t;   
    }
    R[n+1] = n+1;
    bep(i, n, 1) {
        int t = i + 1;
        while(t <= n && arr[t] < arr[i]) t = R[t];
        R[i] = t;
    }
    dfs(1, n, 1);
    rep(i, 1, n) depst[i][0] = deep[i];

    rep(j, 1, 20) {
        int i = 1;
        while(i + (1 << j) - 1 <= n) {
            depst[i][j] = max(depst[i][j-1], depst[i + (1 << (j-1))][j-1]);
            i++;
        }
    }
    rep(i, 1, m) {
        int l, r;
        cin >> l >> r;
        if(r == 0) cout << depst_query(L[l] + 1, R[l] - 1) - deep[l] << endl;
        else {
            if(l > r) swap(l, r);
            if(l == r || (r - l == 1 && arr[l] == arr[r])) {
                cout << 0 << endl;
                continue;
            }
            if(r - l > 1 && arr[st_query(l + 1, r - 1)] >= max(arr[l], arr[r])) {
                cout << 0 << endl;
                continue;
            }
            cout << abs(deep[l] - deep[r]) << endl;
        }
    }
    return 0;
}

Flying Squirrel --- Gym - 102091A(RMQ + 思维)

标签:参数   mem   要求   问题   题目   color   https   swap   inf   

原文地址:https://www.cnblogs.com/Stay-Online/p/12189297.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!