/* HDU 6038 - Function [ 置换,构图 ] 题意: 给出两组排列 a[], b[] 问 满足 f(i) = b[f(a[i])] 的 f 的数目 分析: 假设 a[] = {2, 0, 1} 则 f(0) = b[f(2)] f(1) = b[f(0)] f(2) = b[f(1)] 即 f(0) = b[b[b[f(0)]]] f(1) = b[b[b[f(1)]]] f(2) = b[b[b[f(2)]]] 由于将 a[i]->i 连边可以得到不相交的多个循环 可以看出对于 a[] 中的每一个循环,满足条件 f 的个数即 b[] 中循环长度为其循环长度约数的循环 故对于a中每个循环,找出b中循环长度为其长度的约数的循环个数,再把每个循环的个数乘起来 */ #include <bits/stdc++.h> using namespace std; #define LL long long const LL MOD = 1e9+7; const int N = 1e5+5; int n, m; int a[N], b[N]; int fa[N], fb[N]; int sa[N], sb[N]; int num[N]; int sf(int x, int f[]) { return x == f[x] ? x : f[x] = sf(f[x], f); } int main() { int tt = 0; while (~scanf("%d%d", &n, &m)) { for (int i = 0; i <= max(n, m); i++) { fa[i] = fb[i] = i; sa[i] = sb[i] = num[i] = 0; } for (int i = 0; i < n; i++) { scanf("%d", &a[i]); fa[sf(i,fa)] = sf(a[i], fa); } for (int i = 0; i < m; i++) { scanf("%d", &b[i]); fb[sf(i,fb)] = sf(b[i], fb); } for (int i = 0; i < n; i++) sa[sf(i, fa)]++; for (int i = 0; i < m; i++) sb[sf(i, fb)]++; for (int i = 0; i < m; i++) num[sb[i]]++; LL ans = 1; for (int i = 0; i < n; i++) { if (sa[i]) { LL cnt = 0; for (int j = 1; (LL)j*j <= sa[i]; j++) { if (sa[i] %j == 0) { int k = sa[i] / j; cnt = (cnt + (LL)j*num[j]) % MOD; if (k != j) cnt = (cnt + (LL)k*num[k]) % MOD; } } ans = ans * cnt % MOD; } } printf("Case #%d: %lld ", ++tt, ans); } }