

题意:
现在有一个长度为 n 的一维数组,第 i 个元素 a[i] 表示的是在位置 i 上能直接跳转到的下一个位置。
接下来你要进行 m 次游戏,每次被人抛出一个询问,询问以区间的形式,给定区间 [l, r],问你在这个区间最多能进行几次跳跃,如果永远跳不出,就输出 inf。
思路:

时间复杂度:
O(n∗logn+m∗logn)O(n * logn + m * logn)O(n∗logn+m∗logn)
代码:
#include <bits/stdc++.h>
using namespace std;
//#define int long long
//#define map unordered_map
//int128 ORZ
/*
__int128 read() {
__int128 x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void print(__int128 x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
*/
const int N = 2e5 + 10, M = 28;
int n, m;
int a[N];
int fa[N][M], mn[N][M], mx[N][M];
inline void init()
{
for (int i = 1; i < M; ++i) {
for (int j = 1; j < N; ++j) {
int pre = fa[j][i - 1];
fa[j][i] = fa[pre][i - 1];
mn[j][i] = min(mn[j][i - 1], mn[pre][i - 1]);
mx[j][i] = max(mx[j][i - 1], mx[pre][i - 1]);
}
}
}
inline void solve()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
fa[i][0] = mn[i][0] = mx[i][0] = a[i];
}
init();
while (m--)
{
int l, r, x; cin >> l >> r >> x;
int ans = 0;
for (int i = M - 1; i >= 0; --i)
{
if (l <= mn[x][i] && mx[x][i] <= r) {
ans += 1 << i;
x = fa[x][i];
}
}
if (ans > n) cout << "INF" << '\n';
else cout << ans << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int _ = 1; //cin >> _;
while (_--)
{
solve();
}
return 0;
}
这篇文章介绍了一个基于动态规划的算法来解决一维数组中的跳跃游戏问题。给定一个数组,每个元素表示可跳跃的位置,对于每次询问的区间[l,r],求出最多能进行的跳跃次数。算法的时间复杂度为O(n*logn+m*logn),其中n是数组长度,m是询问次数。文章提供了C++代码实现。
&spm=1001.2101.3001.5002&articleId=128017155&d=1&t=3&u=8161ff03945243dbbdbdeab5774a0a35)
63

被折叠的 条评论
为什么被折叠?



