hdu 5392

Sample Input
2 3 1 3 2 6 2 3 4 5 6 1
 
Sample Output
2 6


题意:给一个转置求它的循环长度

题解:分解成循环求最小公倍数


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MOD 3221225473
#define N 100005
#define MIN 0
#define MAX 1000001

const int maxn = 3000005;
int a[maxn],vis[maxn],sum[maxn];

void fin(int num)
{
    int tt;
    for(int i = 2; i <= num; i++)
    {
        tt = 0;
        while(num%i == 0)
        {
            num/=i;
            tt++;
        }
        if(tt > sum[i])
            sum[i] = tt;
    }
}

ll pow_mod(ll q,int n,ull mod)
{
    if(n == 0)
        return 1;
    ll x = pow_mod(q,n/2,mod);
    ll ans = (ll)x*x%mod;
    if(n %2 == 1)
        ans = ans *q % mod;
    return ans;
}

int main()
{
    int n,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        ll ans;
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        memset(vis,0,sizeof(vis));
        memset(sum,0,sizeof(sum));
        for(int i = 1; i <= n; i++)
        {
            if(vis[i])
                continue;
            int tmp = i;
            int num = 0;
            while(!vis[tmp])
            {
                vis[tmp] = 1;
                tmp = a[tmp];
                num ++;
            }
            //printf("num:%d
",num);
            fin(num);
        }

        ans = 1;
        for(int i = 2; i <= n; i++)
            if(sum[i])
            {
                //printf("%d
",sum[i]);
                ans = (ans * pow_mod(i,sum[i],(ll)MOD))%MOD;
            }
        printf("%I64d
",ans);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Przz/p/5409775.html