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(飞碟现在分词做定语此处不是正在) running
使用 mybatis + flying-0.9.4 的电商后端