hdu5392 Infoplane in Tina Town(LCM + 快速幂取模)

题目链接: hdu5392 ( Infoplane in Tina Town )

说来惭愧,鄙人费了好些功夫才读懂题意。。

​ 对第一个样例: \({1,2,3}\) 执行一次宏变为 \(1,3,2\) ,再执行一次宏变为 \(1,2,3\) 。执行两次宏后回到原序列,因此答案为 \(2\)

​ 对第二个样例: \(1,2,3,4,5,6\) 执行一次宏变为 \(2,3,4,5,6,1\) ,再执行一次宏变为 \(3,4,5,6,1,2\) ,以此类推,直至序列变回 \(1,2,3,4,5,6\) 。执行六次宏后回到原序列,因此答案为 \(6\)

事实上,在第一个样例中数字 \(1\) 执行 \(0\) 次复位,数字 \(2\) 执行 \(2\) 次复位,数字 \(3\) 执行 \(2\) 次复位,于是整体执行 \(LCM(0,2,2)=2\) 次后复位。同理,第二个样例整体执行 \(LCM(6,6,6,6,6,6)=6\) 次后复位。

输入数据量大,需要关闭流同步,或者使用 \(c\) 的输入方式。

/**
 * hdu5392 Infoplane in Tina Town
 * LCM + 快速幂取模
 */

#include <iostream>
#include <vector>
using namespace std;

typedef unsigned long long LL;

LL fastPow(LL a, LL b, LL mod = LLONG_MAX)
{
    a %= mod;
    LL t = 1;
    while (b) {
        if (b&1) t = t*a%mod;
        a = a*a%mod;
        b >>= 1;
    }
    return t%mod;
}

LL mod = 3221225473LL;

void counting(int n, vector<int>& num)
{
    for (int i = 2; i*i <= n; ++i) {
        int cnt = 0;
        while (n%i == 0) n /= i, ++cnt;
        num[i] = max(num[i], cnt);
    }
    if (n != 1) num[n] = max(num[n], 1);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        vector<int> A(n+1), num(n+1);
        vector<bool> vis(n+1);
        for (int i = 1; i <= n; ++i) cin >> A[i];
        for (int i = 1; i <= n; ++i) {
            if (vis[i]) continue;
            int cnt = (A[i] != i);
            int p = i;
            while (A[p] != i) p = A[p], vis[p] = 1, ++cnt;
            counting(cnt, num);
        }
        LL ans = 1;
        for (int i = 2; i <= n; ++i) {
            ans *= fastPow(i, num[i], mod);
            ans %= mod;
        }
        if (ans == 1) ans = 0;
        cout << ans << endl;
    }
    return 0;
}

posted @ 2021-01-30 13:46  Zewbie  阅读(134)  评论(0)    收藏  举报