标签:highlight dfs pre ++z nts efi bool lca int
把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; }
标签:highlight dfs pre ++z nts efi bool lca int
原文地址:http://www.cnblogs.com/autsky-jadek/p/7236671.html