题目链接:点击打开链接
题目大意:给出一种操作a[1],a[2],,,,a[n],代表每交换一次,1位置的数到a[1]位置,2位置的数到a[2]位置,,,
问最终交换多少次可以恢复初始的情况。
题目给出一个置换,要求置换的次数,也就是所有轮换个数的最小公倍数。首先求出所有轮换的个数,然后求最小公倍数的时候不能用gcd,因为Mod的取余太大,所以用质因子分解,统计每个质因子出现的最多次数,计算最终的值。
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <cmath>
#include <map>
#include <stack>
#include <algorithm>
#include <time.h>
using namespace std ;
#pragma comment(linker, "/STACK:102400000,102400000")
#define LL __int64
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define maxn 3000010
const LL Mod = 3221225473 ;
int a[maxn] , sum[maxn] , vis[maxn] ;
int main() {
int t , n , i , j , num , temp , cnt ;
LL ans ;
scanf("%d", &t) ;
while( t-- ) {
scanf("%d", &n) ;
for(i = 1 ; i <= n ; i++) {
scanf("%d", &a[i]) ;
sum[i] = vis[i] = 0 ;
}
for(i = 1 ; i <= n ; i++) {
if( vis[i] ) continue ;
vis[i] = 1 ;
num = 1 ;
j = a[i] ;
while( !vis[j] ) {
num++ ;
vis[j] = 1 ;
j = a[j] ;
}
for(j = 2 , temp = num ; j*j <= num ; j++) {
if( temp%j ) continue ;
cnt = 0 ;
while( temp%j == 0 ) {
temp /= j ;
cnt++ ;
}
sum[j] = max(sum[j],cnt) ;
if( temp == 1 ) break ;
}
if( temp > 1 ) sum[temp] = max(sum[temp],1) ;
}
for(i = 2 , ans = 1 ; i <= n ; i++) {
for(j = 0 ; j < sum[i] ; j++)
ans = ans*i%Mod ;
}
printf("%I64d\n", ans) ;
}
return 0 ;
}
版权声明:转载请注明出处:http://blog.csdn.net/winddreams
hdu5392--Infoplane in Tina Town(置换群+质因子分解求最小公倍数)
原文:http://blog.csdn.net/winddreams/article/details/47726271