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

Posted stay-online

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 区间处理当前区间最高几个机场的深度即可。

#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 + 思维)的主要内容,如果未能解决你的问题,请参考以下文章

flying saucer 修改报表格式

英语里 现在分词做定语flying saucer(飞碟现在分词做定语此处不是正在) running

使用 mybatis + flying-0.9.4 的电商后端

SQUIRREL语言的中文介绍

Squirrel语言初探(可以使用VC6或者MinGW编译)

HSQLDB + SQuirreL:按块读取数据