您的位置:首页 > 大数据 > 人工智能

hdu 6038 找规律 置换 2017 Multi-University Training Contest - Team 1

2017-07-26 09:48 686 查看

Function

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 548    Accepted Submission(s): 215


[align=left]Problem Description[/align]
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.
 

[align=left]Input[/align]
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.
 

[align=left]Output[/align]
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.
 

[align=left]Sample Input[/align]

3 2
1 0 2
0 1
3 4
2 0 1
0 2 3 1

 

[align=left]Sample Output[/align]

Case #1: 4
Case #2: 4

 

[align=left]Source[/align]
2017 Multi-University Training Contest - Team 1

题意:

给出两个序列,一个是0~n-1的排列a,另一个是0~m-1的排列b,现在求满足

的f的个数

题解:

由第二个样例:



对于这组数来说,假如我们先指定了f(0)对应的在b中的值,那么根据第2个式子,就可以得出f(1),根据f(1)就又可以得出f(2),最后根据f(2)就可以检验f(0)的值是否正确。

这也就是说,对于a中的一个循环节,只要确定了其中一个数所映射的值,那么其它数就都被相应的确定了。



所以我们需要先计算出a和b中的循环节个数和每个循环节对应的个数,然后根据循环节的约数关系就可以判断是否成立

答案就是:

当b中的循环节的长度是a的循环节长度的约数的时候,a循环节可以指定数字的个数是b的循环节长度

这里有一个规律就是:0~n 的排列,是一定存在循环节的,而且多个循环节是不会有交叉的,所以最后的结果应该相乘

#include<vector>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define MAXN 100005
#define LL long long
const LL mod=1e9+7;
int a[MAXN],b[MAXN],visit[MAXN];
vector<int>A,B;

int main()
{
int n,m;
int cases=1;
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<m;i++)
scanf("%d",&b[i]);
A.clear();
B.clear();

int cnt,pos;
memset(visit,0,sizeof(visit));
for(int i=0;i<n;i++){
cnt=1,pos=i;
if(!visit[i]){
visit[i]=1;
while(a[pos]!=i)
{
cnt++;
pos=a[pos];
visit[pos]=1;
}
A.push_back(cnt);
}
}

memset(visit,0,sizeof(visit));
for(int i=0;i<m;i++){
cnt=1,pos=i;
if(!visit[i]){
visit[i]=1;
while(b[pos]!=i)
{
cnt++;
pos=b[pos];
visit[pos]=1;
}
B.push_back(cnt);
}
}

LL ans=1,temp;
for(int i=0;i<A.size();i++){
temp=0;
for(int j=0;j<B.size();j++){
if(A[i]%B[j]==0)
temp=(temp+B[j])%mod;
}
ans=ans*temp%mod;
}
printf("Case #%d: %d\n",cases++,ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐