等幂映射是这样定义的,对于一个映射 g : {1,2,...,n} → {1,2,...,n} ,对于所有的 x∈ {1,2,...,n} , g(g(x))=g(x)始终成立。
f(k)(x) 表示将映射f作用于x上k次的结果。一般的, f(1)(x) = f(x) , f(k)(x) = f(f(k−1)(x)) 对于所有的k>1成立。
现在给定一个映射 f : {1,2,...,n} → {1,2,...,n} 。你的任务是寻找最小的k使得 f(k)(x) 是一个等幂映射。
样例解释:这个例子中 f(x) = f(1)(x) 已经是一个等幂映射,因为他已经满足定义: f(f(1))=f(1)=1, f(f(2))=f(2)=2, f(f(3))=f(3)=2,f(f(4))=f(4)=4。
Input
单组测试数据。 第一行包含一个整数 n (1 ≤ n ≤ 200)。 第二行给出 f(1), f(2), ..., f(n) (1 ≤ f(i) ≤ n)。
Output
输出最小满足条件的k。
Input示例
4 1 2 2 4
Output示例
1#include <stdio.h> #include <cstring> #include <iostream> using namespace std; typedef long long ll; const int MAXN = 210; int f[MAXN]; int m[MAXN]; ll gcd(ll a, ll b) { if (b == 0) { return a; } return gcd(b, a % b); } ll lcm(ll a, ll b) { return a / gcd(a, b) * b; } int main() { int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> f[i]; } int j, next; ll result = 1; ll temp; int top = 1; for (int i = 1; i <= n; ++i) { memset(m, 0, sizeof(m)); j = i; m[f[j]] = 1; while (true) { next = f[j]; if (m[f[next]]) { temp = m[f[j]] + 1 - m[f[next]]; if (top < m[f[next]]) { top = m[f[next]]; } break; } m[f[next]] = m[f[j]] + 1; j = next; } result = lcm(result, temp); } temp = result; while (result < top) { result += temp; } cout << result << endl; return 0; }