Function
Problem Description
You are given a permutation a from 0 to n−1 and a permutation b from 0 to m−1.
Define that the domain of function f is the set of integers from 0 to n−1, and the range of it is the set of integers from 0 to m−1.
Please calculate the quantity of different functions f satisfying that f(i)=bf(ai) for each i from 0 to n−1.
Two functions are different if and only if there exists at least one integer from 0 to n−1 mapped into different integers in these two functions.
The answer may be too large, so please output it in modulo 109 +7.
Input
The input contains multiple test cases.
For each case:
The first line contains two numbers n, m. (1≤n≤100000,1≤m≤100000)
The second line contains n numbers, ranged from 0 to n−1, the i-th number of which represents ai−1.
The third line contains m numbers, ranged from 0 to m−1, the i-th number of which represents bi−1.
It is guaranteed that ∑n≤ 106 , ∑m≤ 106 .
Output
For each test case, output “Case #x: y” in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
Sample Input
3 2
1 0 2
0 1
3 4
2 0 1
0 2 3 1
Sample Output
Case #1: 4
Case #2: 4
题意:给你一个a数组和b数组,叫你构造f函数满足所有的f(i)=bf(ai)
解题思路:对于a数组中的一个长度为l的环,我们只需要找在b中长度为 l的约数的环使得a数组中的数与b数组中的数一一对应就好,例如a={1,2,3,0},b={1,0},则我们可以让a0->b1,a1->b0,a2->b1,a3->b0或者a0->b0,a1->b1,a2->b0,a3->b1,则这样就是两种情况,然后我们能得知,对于两个对应的a,b环,f的种类其实就为b环的长度,因此我们便可以直接得出ans=(b中与a环对应的环的长度的总和相乘)
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,m,a[100005],b[100005],mark[100005];
ll len;
ll s2[100005];
ll ans;
const ll mod=1000000007;
vector<ll>p[100005];
vector<ll>q;
void init(){
for(ll i=1;i<=100000;i++){
for(ll j=1;j*j<=i;j++){
if(i%j==0&&j*j!=i){
p[i].push_back(j);
p[i].push_back(i/j);
}
else if(i%j==0&&j*j==i) p[i].push_back(j);
}
}
}
int main(){
init();
ll cas=1;
while(scanf("%lld%lld",&n,&m)!=EOF){
q.clear();
ans=1;
memset(s2,0,sizeof(s2));
for(ll i=0;i<n;i++) scanf("%lld",&a[i]);
for(ll i=0;i<m;i++) scanf("%lld",&b[i]);
memset(mark,0,sizeof(mark));
for(ll i=0;i<n;i++){
if(mark[i]==0){
mark[i]=1;
len=1;
ll now=a[i];
while(mark[now]==0){
mark[now]=++len;
now=a[now];
}
q.push_back(len);
}
}
memset(mark,0,sizeof(mark));
for(ll i=0;i<m;i++){
if(mark[i]==0){
mark[i]=1;
len=1;
ll now=b[i];
while(mark[now]==0){
mark[now]=++len;
now=b[now];
}
s2[len]++;
}
}
for(ll i=0;i<q.size();i++){
ll sum=0;
for(ll j=0;j<p[q[i]].size();j++){
sum=(sum+s2[p[q[i]][j]]*p[q[i]][j])%mod;
}
ans=(ans*sum)%mod;
}
printf("Case #%lld: %lld\n",cas++,ans);
}
return 0;
}