Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3245 | Accepted: 1766 |
Description
This record defines a permutation P as follows: P(1) = 4, P(2) = 1, P(3) = 5, etc.
What is the value of the expression P(P(1))? It’s clear, that P(P(1)) = P(4) = 2. And P(P(3)) = P(5) = 3. One can easily see that if P(n) is a permutation then P(P(n)) is a permutation as well. In our example (believe us)
It is natural to denote this permutation by P2(n) = P(P(n)). In a general form the defenition is as follows: P(n) = P1(n), Pk(n) = P(Pk-1(n)). Among the permutations there is a very important one — that moves nothing:
It is clear that for every k the following relation is satisfied: (EN)k = EN. The following less trivial statement is correct (we won't prove it here, you may prove it yourself incidentally): Let P(n) be some permutation of an N elements set. Then there exists a natural number k, that Pk = EN. The least natural k such that Pk = EN is called an order of the permutation P.
The problem that your program should solve is formulated now in a very simple manner: "Given a permutation find its order."
Input
Output
Sample Input
5 4 1 5 2 3
Sample Output
6
Source
Ural State University Internal Contest October'2000 Junior Session
解題思路:一個數在置換過程中不斷變化,進過若干步之後肯定會變成原來的值,所以我們求出每個數置換爲原來的值得循環節,然後對這些循環節求一個最小公倍數就行。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 1000 + 10;
int N;
int p[maxn];
int a[maxn];
int cir[maxn];
LL gcd(LL x, LL y)
{
return x == 0 ? y : gcd(y % x, x);
}
LL lcm(LL x, LL y)
{
return (x * y) / gcd(x, y);
}
int main()
{
scanf("%d", &N);
for(int i = 1; i <= N; i++)
{
scanf("%d", &p[i]);
a[i] = i;
}
for(int i = 1; i <= N; i++)
{
int ans = 1;
while(p[a[i]] != i)
{
a[i] = p[a[i]];
ans++;
}
cir[i] = ans;
}
LL ans = 1;
for(int i = 1; i <= N; i++)
{
ans = lcm(ans, (LL)cir[i]);
}
printf("%lld\n", ans);
return 0;
}