2017多校第一场 HDU 6038 Function 循环节,脑洞,大思维题
来源:互联网 发布:管家婆数据导入 编辑:程序博客网 时间:2024/06/06 12:59
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序列,代表0到n-1的排列;一个b序列代表0到m-1的排列。问你可以找出多少种函数关系,满足f(i)=b[f(a[i])]
解法:
看一下第二组样例:
对于这个样例,假如我们确定了f(0)在b中的值,那么根据第二个式子,就可以得到f(1),同理通过f(1)可以得到f(2),最后根据f(2)反推回来就可以判断f(0)是不是正确。也就是说,对于a中的一个循环节只要确定其中一个数映射的值,那么这个循环节其他的数就确定了。
所以我们需要先计算a,b的循环节和每个循环节节的个数,然后根据循环节的约数关系就可以判断是否成立。
如何求答案呢?当b中的循环节的长度是a的循环节长度的约数的时候,a循环节可以指定数字的个数是b的循环节长度。这里有一个规律就是:0~n 的排列,是一定存在循环节的,而且多个循环节是不会有交叉的,所以最后的结果应该相乘。
#include <bits/stdc++.h>using namespace std;typedef long long LL;const LL mod = 1e9+7;const int maxn = 1e5+6;int n, m, a[maxn], b[maxn], loop_a[maxn], loop_b[maxn], vis[maxn];LL qsm(int a, int n){ int ret = 1; while(n){ if(n&1) ret=1LL*ret*a%mod; a=1LL*a*a%mod; n>>=1; } return ret;}int main(){ int ks = 0; while(~scanf("%d %d", &n,&m)){ 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)); memset(loop_a, 0, sizeof(loop_a)); memset(loop_b, 0, sizeof(loop_b)); for(int i=0; i<n; i++){ if(!vis[i]){ int x = a[i]; int cnt = 0; while(!vis[x]){ cnt++; vis[x]=1; x=a[x]; } loop_a[cnt]++; } } memset(vis, 0, sizeof(vis)); for(int i=0; i<m; i++){ if(!vis[i]){ int x = b[i]; int cnt = 0; while(!vis[x]){ cnt++; vis[x]=1; x=b[x]; } loop_b[cnt]++; } } LL ans=1; for(int i=1; i<=n; i++){ LL ret = 0; for(int j=1; j*j<=i; j++){ if(i%j==0){ int k = j; ret += 1LL * loop_b[j] * j; if(j*j != i){ k = i / j; ret += 1LL * loop_b[k] * k; } } } int x = loop_a[i]; ans = 1LL * ans * qsm(ret, x)%mod; } printf("Case #%d: %lld\n", ++ks, ans); } return 0;}
- 2017多校第一场 HDU 6038 Function 循环节,脑洞,大思维题
- 2017多校联合第一场 1006题 hdu 6038 Function 循环节
- 2017 多校训练第一场 HDU 6038 Function
- 2017多校第一场 1006 Function
- 2017多校第一场 HDU 6044 Limited Permutation 思维,计数,DFS
- 2017多校第一场1006 function(HDU6038)
- HDU 6040 2017多校第一场
- hdu 6038 Function(思维)
- HDU 6038 Function【思维】
- hdu 6038 Function 循环节
- 【2017多校第二场】HDU 6075 Questionnaire【思维】
- 2017多校第二场 HDU 6052 To my boyfriend 思维,计数题
- hdu 6060 RXD and dividing 2017多校第三场第五题(思维+dfs)
- HDU-6038 Function(思维)
- HDU 6034-(2017多校第一场 Balala Power!)(贪心)
- hdu 4862 jump 多校第一场第二题
- hdu 5288||2015多校联合第一场1001题
- 多校第一场:hdu 4308(bfs)
- 安卓权限了解
- datagrid 多选分页保留选中项
- 数据挖掘和机器学习中距离和相似度公式
- 解题报告:HDU_6042 Journey with Knapsack 生成函数
- Storm集群的搭建
- 2017多校第一场 HDU 6038 Function 循环节,脑洞,大思维题
- 2017第一次多校联合 1006Function
- PAT乙级 1052. 卖个萌 (20)--格式化读取,vector的使用
- [PAT乙级]1046. 划拳(15)
- 10562
- layui框架详细分析系列之框架主体组织结构
- Eclipse中项目切换SVN路径
- python读取并写入mat文件
- CSU 1969 TFSudoku 特殊数独