2017 Multi-University Training Contest - Team 1 1006&&HDU 6038 Function【DFS+数论】
2017-07-26 11:51
519 查看
Function
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 652 Accepted Submission(s): 267
[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
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6038
分析:
题目大意:
给你一个数组A,和一个数组B,数组A是【0~n-1】的排咧,数组B是【0~m-1】的排列。
现在定义F(i)=bF(ai);
问有多少种取值,使得F(i)全部合法。
样例1可行的解:
110
111
001
000
分析:
写出样例2的公式:
①F(0)=bF(2)
②F(1)=bF(0)
③F(2)=bF(1)
我们不难发现,如果我们设定了F(0)的值,就能够通过式子②能够得知F(1)的值,然后就能通过式子③得知F(2)的值,最后再回归式子①尝试当前设定的值是否合法了。
这就是一个循环节
我们对于A数组中的一个环的话如果一个环中的任意一个点的价值我们能够设定出来,那么这一个循环节的所有点的值就都能够知道了。
然而这个能够设定的值,肯定是数组B中的一个值,而且我们已知都是循环节,那么数组B中的这个被选中设定的值也一定存在一个循环节,而且这个循环节的长度,一定是A长度循环节的因子长度。
A数组中长度为D的一个循环节,如果B数组中有一个循环节的长度为d,并且如果D%d==0.那么这个B数组的这个循环节的所有值,都可以作为A数组中这个循环节的值。那么对于A数组中的这个循环节来讲,答案数就多了d个。
过程统计每个循环节能够满足的答案的个数,然后累乘即可。
下面给出AC代码:
#include <bits/stdc++.h> using namespace std; const int maxn=100010; const int mod=1000000007; int n,m,ans=1; int a[maxn],b[maxn]; int cal[2][maxn]; bool vis[maxn]; inline void DFS(int t,int l,int *a,int k) { if(vis[t]) { cal[k][l]++; return; } vis[t]=1; DFS(a[t],l+1,a,k); } int main() { int tcase=1; 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]); memset(cal,0,sizeof(cal)); memset(vis,false,sizeof(vis)); for(int i=0;i<m;i++) { if(!vis[i]) DFS(i,0,b,0); } memset(vis,false,sizeof(vis)); for(int i=0;i<n;i++) { if(!vis[i]) DFS(i,0,a,1); } ans=1; for(int i=1;i<=n;i++) { if(cal[1][i]) { int lim=(int)sqrt(i+0.5); int ta=0; for(int j=1;j<=lim;j++) { if(i%j==0) { (ta+=(long long)cal[0][j]%mod*j%mod)%=mod; if(j*j!=i) (ta+=(long long)cal[0][i/j]%mod*(i/j)%mod)%=mod; } } for(int j=1;j<=cal[1][i];j++) { ans=(long long)ans*ta%mod; } } } printf("Case #%d: %d\n",tcase++,ans); } return 0; }
相关文章推荐
- 2017 Multi-University Training Contest - Team 1(hdu 6038 Function)
- HDU 6038 Function(找规律)——2017 Multi-University Training Contest - Team 1
- HDU-6038 Function - 2017 Multi-University Training Contest - Team 1(构造置换或强连通分量)
- 2017 Multi-University Training Contest - Team 5:1006&hdu6090、 Rikka with Graph
- 2017 Multi-University Training Contest - Team 9 1003&&HDU 6163 CSGO【计算几何】
- 2017 Multi-University Training Contest - Team 2 :1006 Funny Function(找规律+逆元+快速幂取模)
- 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】
- HDU 6034 & 2017 Multi-University Training Contest - Team 1
- hdu 6038 找规律 置换 2017 Multi-University Training Contest - Team 1
- HDU 6134 Battlestation Operational(基本数论+莫比乌斯反演)——2017 Multi-University Training Contest - Team 8
- 2017 Multi-University Training Contest - Team 9 1004&&HDU 6164 Dying Light【数学+模拟】
- HDU 6165 - FFF at Valentine DFS暴力 2017 Multi-University Training Contest - Team 9
- 2017 Multi-University Training Contest - Team 9 1005&&HDU 6165 FFF at Valentine【强联通缩点+拓扑排序】
- HDU 6128 Inverse of sum(数论)——2017 Multi-University Training Contest - Team 7
- 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】
- 2017 Multi-University Training Contest - Team 1--1006 Function
- 2017 Multi-University Training Contest - Team 1 1006 Function(置换群)
- 2017 Multi-University Training Contest 1 && HDOJ 6038 Function 【强连通找环】
- 2017 Multi-University Training Contest - Team 1 1006 Function
- 2017 Multi-University Training Contest - Team 1 1006 Function(思维 循环节)