Function
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1649 Accepted Submission(s): 773
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.
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.
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序列,代表0到n-1的排列;一个b序列代表0到m-1的排列。问你可以找出多少种函数关系,满足f(i)=b[f(a[i])];
分析:这个主要是找循环节
比如说:如果 a 序列是 2 0 1 那么我们可以发现
f(0) = b[f(a[0])] = b[f(2)]
f[1] = b[f(a[1])] = b[f(0)]
f[2] = b[f(a[2])] = b[f(1)]
那么f(0) f(1) f(2) 也是循环的 如果想找出这样的函数,必须值域里也存在同样长度的循环节或者存在其约数长度的循环节。
那么就是找两个序列的循环节,对于定义域里面的每一个循环节都找出来有多少种和他对应的。最后乘起来就是答案了
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
#define ll long long
#define mod 1000000007
#define N 100050
vector<int>vec;
vector<int>F[N];
void init(){
for(int i = 1;i <= N - 10;i++){
for(int j = i;j <= N - 10;j += i){
F[j].push_back(i);
}
}
}
int a[N],b[N],vis[N],blen[N];
int dfs(int x,int *p){
if(vis[x])
return 0;
vis[x] = 1;
return dfs(p[x],p) + 1;
}
int main(){
int n,m,Case = 1;
init();
while(scanf("%d %d",&n,&m) != EOF){
vec.clear();
for(int i = 0;i < n;i++){
scanf("%d",&a[i]);
}
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]){
vec.push_back(dfs(i,a));
}
}
memset(vis,0,sizeof(vis));
memset(blen,0,sizeof(blen));
for(int i = 0;i < m;i++){
if(!vis[i]){
blen[dfs(i,b)]++;
}
}
ll ans = 1;
for(int i = 0;i < vec.size();i++){
ll temp = 0;
for(int j = 0;j < F[vec[i]].size();j++){
temp += F[vec[i]][j] * blen[F[vec[i]][j]];
temp %= mod;
}
ans *= temp;
ans %= mod;
}
printf("Case #%d: %lld\n",Case++,ans);
}
}

本文探讨了一个复杂的函数计数问题,给定两个排列序列a和b,寻找满足特定条件的函数数量。通过对序列循环特性的深入分析,提出了一种有效的解决策略,并通过代码实现了算法。
426

被折叠的 条评论
为什么被折叠?



