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

2017 Multi-University Training Contest - Team 1 1006 Function

2017-07-26 15:15 351 查看

Function

[align=center]Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 842    Accepted Submission(s): 370
[/align]

[align=left]Problem Description[/align]

You are given a permutationa
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 from0
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

 

题目大意:

给你一个数组A,和一个数组B,数组A是【0~n-1】的排咧,数组B是【0~m-1】的排列。

现在定义F(i)=bF(ai);问有多少种取值,使得F(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<cstdio>
#include<map>
#include<cstring>
#define mo 1000000007
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;

ll a[maxn];
ll b[maxn];
ll num1[maxn], num2[maxn];
int main()
{
int n, m, kase = 0;
while (~scanf("%d%d", &n, &m))
{
memset(num2, 0, sizeof(num2));

int totfa = 0;
for (int i = 0; i < n; i++)
{
scanf("%lld", &a[i]);
}
for (int i = 0; i < n; i++)
{
ll tot = 0;
int k = i;
while (a[k] != -1)
{
tot++;
int t = k;
k = a[k];
a[t] = -1;
}
if (tot)
{
num1[++totfa] = tot;
}
}

for (int j = 0; j < m; j++)
{
scanf("%lld", &b[j]);
}
for (int i = 0; i < m; i++)
{
ll tot = 0;
int k = i;
while (b[k] != -1)
{
tot++;
int t = k;
k = b[k];
b[t] = -1;
}
if (tot)
{
num2[tot]++;
}
}

ll ans = 1;
for (int i = 1; i <= totfa; i++)
{
ll ansl = 0;
for (int j = 1; j * j <= num1[i]; j++)
{
if (num1[i] % j == 0)
{
if (j * j == num1[i])
{
ansl += num2[j] * j;
}
else
{
ansl += num2[j] * j + num2[num1[i] / j] * num1[i] / j;
}
}
}
ans = (ans * ansl) % mo;
}
printf("Case #%d: %lld\n", ++kase, ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm 多校训练 模拟