


算法: 并查集找定义域的环,值域的环。
对于定义域内的大小为x的环
枚举值域里 大小为y 的环 x%y==0
具体在代码。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define q (int)
const ll mod = 1e9 + 7;
int a[q 1e6], b[q 1e6];
struct un {
int fa[q 1e7];
int sz[q 1e7];
void init(int n) {
for (int i = 0; i <= n; i++) {
fa[i] = i;
sz[i] = 0;
}
}
int tofind(int x) {
if (x == fa[x]) return x;
else return fa[x] = tofind(fa[x]);
}
void unite(int x, int y) {
x = tofind(x);
y = tofind(y);
if (x != y) {
fa[x] = y;
}
}
void clear(int n){
for (int i = 0; i <= n; i++) {
sz[i] = 0;
}
}
} s[2];
int Size[2][q 1e6]={0};
ll pow_mod(ll x, int n) {
ll res = 1;
while (n > 0) {
if (n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
int main() {
if (fopen("/home/lianyi/123.txt", "r") != NULL) {
freopen("/home/lianyi/123.txt", "r", stdin);
} else {
std::ios::sync_with_stdio(false);
cin.tie(0);
}
int n, m;
int ik = 0;
while (cin >> n >> m) {
ik++;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int j = 0; j < m; j++) {
cin >> b[j];
}
s[0].init(n);
s[1].init(m);
for (int i = 0; i < n; i++) { s[0].unite(i, a[i]); }
for (int j = 0; j < m; j++) { s[1].unite(j, b[j]); }
for (int i = 0; i < n; i++) { s[0].sz[s[0].tofind(i)]++; }
for (int j = 0; j < m; j++) { s[1].sz[s[1].tofind(j)]++; }
for (int i = 0; i < n; i++) {
Size[0][s[0].sz[i]]++;
}
for (int j = 0; j < m; j++) {
Size[1][s[1].sz[j]]++;
}
ll ans = 1;
for (int i = 1; i <= n; i++) {
ll tmp = 0;
if(Size[0][i]==0 ) continue;
int mx=min(m, i);
for (int j = 1; j <=mx; j++) {
if(Size[1][j])
if (i % j == 0) {
tmp = (tmp + (ll)Size[1][j] * j) % mod;
}
}
ll v = pow_mod(tmp, Size[0][i]);
ans = ((ll)ans * v) % mod;
}
cout << "Case #" << ik << ": " << ans << '\n';
int mn=max(m,n);
for(int i=0;i<=mn;i++){
Size[0][i]=Size[1][i]=0;
}
}
return 0;
}