把b数组的所有置换群求出来,用数组记录一下每个大小所出现的次数。
然后求a的置换群,对每个置换群求能被其整除的b的置换群的大小总和(只有这些才能满足构造出一个f,且不自相矛盾),然后把它们全都乘起来就是答案。
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define MOD 1000000007ll
int n,m,a[100010],b[100010],zu;
bool vis[100010];
//ll Quick_Pow(ll a,ll p){
// if(!p){
// return 1;
// }
// ll res=Quick_Pow(a,p>>1);
// res=res*res%MOD;
// if(p&1ll){
// res=(a%MOD*res)%MOD;
// }
// return res;
//}
int nowsiz,cnts[100010];
void dfs(int U){
vis[U]=1;
++nowsiz;
if(!vis[b[U]]){
dfs(b[U]);
}
}
void df2(int U){
vis[U]=1;
++nowsiz;
if(!vis[a[U]]){
df2(a[U]);
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
memset(cnts,0,sizeof(cnts));
++zu;
for(int i=0;i<n;++i){
scanf("%d",&a[i]);
}
for(int i=0;i<m;++i){
scanf("%d",&b[i]);
}
for(int i=0;i<m;++i){
if(!vis[i]){
nowsiz=0;
dfs(i);
++cnts[nowsiz];
}
}
memset(vis,0,sizeof(bool)*m);
ll ans=1;
for(int i=0;i<n;++i){
if(!vis[i]){
nowsiz=0;
df2(i);
int allcanb=0;
for(int i=1;i*i<=nowsiz;++i){
if(nowsiz%i==0){
if(i*i==nowsiz){
allcanb+=cnts[i]*i;
}
else{
allcanb+=cnts[i]*i;
allcanb+=cnts[nowsiz/i]*(nowsiz/i);
}
}
}
ans=ans*(ll)allcanb%MOD;
}
}
printf("Case #%d: %lld\n",zu,ans);
memset(vis,0,sizeof(bool)*n);
}
return 0;
}
原文:http://www.cnblogs.com/autsky-jadek/p/7236671.html