题意
给定一个置换形式如
,问经过几次置换可以变为恒等置换
思路
就是求k使得P
k = I.
我们知道一个置换可以表示为几个轮换的乘积,那么
k就是所有轮换长度的最小公倍数.
把一个置换转换成轮换的方法也很简单,
从一个数出发按照置换图置换,直到置换到已经置换过的数,则这些数就构成一个轮换。
代码
[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, end) for (int i = begin; i <= end; i ++)
using namespace std;
int gcd(int a, int b){
return b?gcd(b, a%b):a;
}
int a[1005];
bool vis[1005];
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int n;
while(scanf("%d", &n) != EOF){
for (int i = 1; i <= n; i ++){
scanf("%d", &a[i]);
}
MEM(vis, false);
int res = 1;
for (int i = 1; i <= n; i ++){
if (!vis[i]){
vis[i] = 1;
int len = 1;
int p = i;
while (1){
p = a[p];
if (vis[p]) break;
vis[p] = 1;
len ++;
}
res = res / gcd(res, len) * len;
}
}
printf("%d
", res);
}
return 0;
}
[/cpp]