一个置换群可以拆成若干个不相交的环,我们把函数在两个环上表示出来。发现 A中环的长度需要是B中环的长度的整数倍。
#include <bits/stdc++.h>
using namespace std;
typedef int lint;
typedef long long LL;
const lint maxn = 100003;
const LL mod = 1e9+7;
lint a[maxn],b[maxn],visb[maxn],visa[maxn],cntb[maxn];
void init(lint n,lint m){
// for( lint i = 0;i < m;i++ ) visb[i] = 0,cntb[i] = 0;
//for(lint i = 0;i < n;i++) visa[i] = 0;
memset( visb,0,sizeof(visb) );
memset(cntb,0,sizeof(cntb));
memset( visa,0,sizeof(visa) );
}
void solveb(lint m){
for( lint i = 0;i < m;i++ ){
if(visb[i]) continue;
lint x = i,tot = 0;
while(!visb[x]){
tot++;visb[x] = 1;
x = b[x];
}
cntb[tot] = (cntb[tot]+ tot)%mod;
}
}
LL solve( lint n ){
LL ans = 1;
for( lint i = 0;i < n;i++ ){
if(visa[i]) continue;
lint x = i,tot = 0;
while(!visa[x]){
tot++;visa[x] = 1;
x= a[x];
}
LL sum = 0;
lint j;
for( j = 1;j*j <= tot;j++ ){
if( tot%j == 0 ) {
if( j*j == tot ) sum = (sum + cntb[j])%mod;
else sum = (sum + cntb[j]+cntb[tot/j])%mod;
}
}
ans = ans * sum % mod;
}
return ans;
}
int main(){
lint ca = 0,n,m;
while( 2 == scanf("%d%d",&n,&m) ){
//scanf("%d%d",&n,&m);
init(n,m);
for( lint i = 0;i < n;i++ ) {scanf("%d",&a[i]);}
for( lint i = 0;i < m;i++ ){scanf("%d",&b[i]);}
solveb(m);
LL ans = solve(n);
printf("Case #%d: %I64d\n",++ca,ans);
}
return 0;
}