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;
}