[R1D]传送
// 4. [R1D]传送.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
#4. [R1D]传送
https://bs.daimayuan.top/p/4
时空限制: 1S/512M
难度: 8
提交: 1043 通过: 134
题目描述:
给定 n 个格子和一个长度为 n 的正整数数组 A1,A2,...,An,当你位于格子 i 时,下一秒你会被传送到格子 Ai。
有 q 个询问,第 i 个询问需要求如果初始位于格子 si, ci 秒后你的位置。
输入格式:
第一行包含一个正整数 n,表示格子的数量。
第二行包含 n 个正整数,分别表示位于每个格子时下一秒的传送位置。
第三行包含一个正整数 q,表示询问的数量。
接下来 q 行,每行包含两个正整数 si 和 ci,表示询问如果初始位于格子 si, ci 秒后你的位置。
输出格式:
对于每个询问,在单独的一行中输出一个整数,表示答案。
样例输入:
5
2 3 5 4 1
2
1 3
4 10086
样例输出:
5
4
数据规模:
对于 100% 的数据,1≤n,q≤2×10^5,1≤Ai,si≤n,1≤ci≤10^9。
测试点分布:
- 测试点 1~2: n≤2000, ci≤20000, q≤2×10^5
- 测试点 3: n≤2×10^5, ci≤20
- 测试点 4~5: n≤2×10^5, ci≤10
- 测试点 6~10: n≤2×10^5, ci≤10^9
*/
#include <iostream>
using namespace std;
const int N = 200010, LOG = 31;
int up[N][LOG];
int a[N];
int n, m;
void pre() {
for (int i = 1; i <= n; i++) up[i][0] = a[i];
//从k开始逐个点计算, 层级深一倍 每个点都计算一次
for (int k = 1; k < LOG; k++) {
for (int i = 1; i <= n; i++) {
up[i][k] = up[up[i][k - 1]][k - 1];
}
}
}
void query(int p, int jump) {
for (int i = 0; i < LOG; i++) {
if ( (jump >> i) & 1) {
p = up[p][i];
}
}
cout << p << endl;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
pre();
cin >> m;
for (int i = 0; i < m; i++) {
int p, t; cin >> p >> t;
query(p,t);
}
return 0;
}
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力

