题意:
给你a数组和b数组, 问你f 函数的种类。 使得a[i] = b[f[a[i]]]?
思路:
因为a 数组 和b 数组 都是0~n-1的排列。
所以一定有一个循环节:
比如 2 1 0 3的话 ,就有两个循环节。
2 1 0 和 3
那么要想使得是一个循环的a 赋值,就也得找b 的循环节。
假如我们得到了b的循环节。
那么对于每一个a 来说, 只要b 是a 的因子, 那么b就可以给a 赋值。方案数是b 循环节的长度。
那么把所有的乘起来即可。
无力吐槽:
因为初始化数组 是循环跑的, 忘记了n 和m 不一定相等, wa了一天。。。。。。。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
const int maxn = 100000 + 10;
int a[maxn];
int b[maxn];
int sum[maxn];
int vis[maxn];
vector<int>va, vb;
void dfs(int cur,int c[],int n,int ans,int flag){
vis[cur] = 1;
if (vis[c[cur] ]) {
if (flag) {
sum[ans]++;
}
else va.push_back(ans);
}
else {
dfs(c[cur], c, n, ans+1, flag);
}
}
const int mod = 1e9 + 7;
void add(long long& ans, long long x){
ans += x;
if (ans >= mod) ans -= mod;
}
int main(){
int n,m;
int ks = 0;
while(~scanf("%d %d",&n, &m)){
va.clear();
for (int i = 0; i < n; ++i){
scanf("%d", a+i);
}
memset(sum,0,sizeof sum); /// 醉了= =
for (int i = 0; i < m; ++i){
scanf("%d",&b[i]);
}
memset(vis,0,sizeof vis);
for (int i = 0; i < n; ++i){
if (!vis[i]){
dfs(i,a, n, 1, 0);
}
}
memset(vis,0,sizeof vis);
for (int i = 0; i < m; ++i){
if (!vis[i]){
dfs(i,b, m, 1, 1);
}
}
long long ans = 1LL;
for (int i = 0; i < va.size(); ++i){
int x = va[i];
int mm = sqrt(x + 0.5);
long long tmp = 0LL;
for (int j = 1; j <= mm; ++j){
if (x % j == 0){
if (j * j != x){
if (sum[j])add(tmp, (long long)j * (long long)sum[j]);
if (sum[x/j])add(tmp, (long long)(x/j) * (long long)sum[x/j] );
}
else {
if (sum[j])add(tmp, (long long)j * (long long)sum[j]);
}
}
}
ans = (ans * tmp) % mod;
}
printf("Case #%d: %I64d\n", ++ks,ans);
}
return 0;
}
/**
3 2
1 0 2
0 1
3 4
2 0 1
0 2 3 1
Case #1: 4
Case #2: 4
**/
FunctionTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1351 Accepted Submission(s): 623
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
Sample Output
Source
Recommend
|
FunctionTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1351 Accepted Submission(s): 623
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
Sample Output
Source
Recommend
|