文章目录
1. 题目描述
1.1. Limit
Time Limit: 2000 ms
Memory Limit: 1024 MB
1.2. Problem Description
The Kingdom of Takahashi has N N N towns, numbered 1 1 1 through N N N.
There is one teleporter in each town. The teleporter in Town i i i ( 1 ≤ i ≤ N ) (1 \leq i \leq N) (1≤i≤N) sends you to Town A i A_i Ai.
Takahashi, the king, loves the positive integer K K K. The selfish king wonders what town he will be in if he starts at Town 1 1 1 and uses a teleporter exactly K K K times from there.
Help the king by writing a program that answers this question.
1.3. Input
N
N
N
K
K
K
A
1
A
2
…
A
N
A_1\ A_2\ \dots \ A_N
A1 A2 … AN
1.4. Constraints
2 ≤ N ≤ 2 × 1 0 5 2 \leq N \leq 2 \times 10^5 2≤N≤2×105
1 ≤ A i ≤ N 1 \leq A_i \leq N 1≤Ai≤N
1 ≤ K ≤ 1 0 18 1 \leq K \leq 10^{18} 1≤K≤1018
1.5. Output
Print the integer representing the town the king will be in if he starts at Town 1 1 1 and uses a teleporter exactly K K K times from there.
1.6. Sample Input 1
4 5
3 2 4 1
1.7. Sample Output 1
4
If we start at Town 1 1 1 and use the teleporter 5 times, our travel will be as follows: 1 → 3 → 4 → 1 → 3 → 4 1 \to 3 \to 4 \to 1 \to 3 \to 4 1→3→4→1→3→4.
1.8. Sample Input 2
6 727202214173249351
6 5 2 5 3 2
1.9. Sample Output 2
2
1.10. Source
2. 解读
将所有路径使用邻接表进行存储,然后对路径依次进行遍历,将遍历过的节点存储在栈 S t a c k Stack Stack中,找出图中的环路。
在节点入栈前,判断其是否在栈中,若在,则该节点首次出现的位置到栈顶位置之间的节点所连成的边即为我们要找的环路 C C C,求出环路长度 S S S。
判断 游走次数 K K K 是否大于图的起点 Q 0 Q_0 Q0 到环路起点 W 0 W_0 W0 的距离 l e n g t h = Q 0 − W 0 length = Q_0 - W_0 length=Q0−W0。
若 K > l e n g t h K > length K>length,则输出 S t a c k Stack Stack 中从 0 0 0 开始计数第 Q 0 + ( K − W 0 ) % S Q_0 + (K - W_0) \% S Q0+(K−W0)%S 个元素。
若 K ≤ l e n g t h K \le length K≤length,则输出 S t a c k Stack Stack 中从 0 0 0 开始计数第 K K K 个元素。
3. 代码
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
const int NUM = 2 * 10e5 + 1;
// 存储
long long list[NUM];
// 标志访问
bool visit[NUM];
// 栈存储访问路径
vector<long long> vec;
int main()
{
// test case
long long n, k;
scanf("%lld %lld", &n, &k);
// 初始化
memset(list, 0, sizeof(list));
memset(visit, 0, sizeof(visit));
// 输入
for (long long i = 0; i < n; i++) {
scanf("%lld", &list[i]);
}
// 初始化
long long buffer = 1;
// 计算
for (int i = 0; i < n; i++) {
// 标志访问
visit[buffer] = 1;
// 节点入栈
vec.push_back(buffer);
// 获取下一个节点
buffer = list[buffer - 1];
// 若形成环路
if (visit[buffer] == 1) {
break;
}
}
// 在栈中找出环路开始位置
auto it = find(vec.begin(), vec.end(), buffer);
// 环路长度
long long cycleLength = vec.end() - it;
// 环路开始前的栈深度
long long stackLength = it - vec.begin();
// 计算从环路起点开始的位移
long long posMark;
if (k > stackLength) {
// 若存在环路
posMark = (k - stackLength) % cycleLength;
} else {
// 若不存在环路
posMark = (k - stackLength);
}
// 输出
printf("%lld\n", vec[stackLength + posMark]);
}
联系邮箱:curren_wong@163.com
Github:https://github.com/CurrenWong
欢迎转载/Star/Fork,有问题欢迎通过邮箱交流。