2017年多校赛第一场 1006 Function(枚举)
2017-07-26 10:20
453 查看
这道题所有情况满足的情况下会构成一个环,我们很容易想到枚举环中的一个点,环中的其他点就都可以得出了。
这道题是问一共有多少种所有情况都满足的情况。所以我们先预处理a里面的循环节,统计一下长度为i的循环节有几个。然后预处理b里面的循环节,同样统计长度为i的循环节有几个。
最后枚举一下,假设a数组中有循环节长度为i,那么在b中枚举循环节为i的因子的。比如j为i的因子,那么此时就会多出j * num_b[j]种情况。枚举完之后,得到a数组中循环节为i时有tmp种情况。那么再看a中有多少个循环节长度为i。假设有两个,也就是a中有两个环同时都有tmp种情况,那么总的情况数就是tmp^2种,答案ans * tmp^2即可。
代码如下:
这道题是问一共有多少种所有情况都满足的情况。所以我们先预处理a里面的循环节,统计一下长度为i的循环节有几个。然后预处理b里面的循环节,同样统计长度为i的循环节有几个。
最后枚举一下,假设a数组中有循环节长度为i,那么在b中枚举循环节为i的因子的。比如j为i的因子,那么此时就会多出j * num_b[j]种情况。枚举完之后,得到a数组中循环节为i时有tmp种情况。那么再看a中有多少个循环节长度为i。假设有两个,也就是a中有两个环同时都有tmp种情况,那么总的情况数就是tmp^2种,答案ans * tmp^2即可。
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> #include <vector> #include <stack> #include <map> #include <set> #include <cmath> #include <cctype> #include <ctime> using namespace std; #define REP(i, n) for (int i = 0; i < (n); ++i) #define eps 1e-9 typedef long long ll; typedef pair<int, int> pii; const int INF = 0x7fffffff; const ll mod = 1e9 + 7; const int maxn = 1e5 + 5; bool vst[maxn]; int n, m; int a[maxn], b[maxn]; int nx[maxn]; ll num_a[maxn], num_b[maxn]; int main() { int Case = 1; while(cin >> n >> m) { for(int i = 0; i < n; i++) scanf("%d", &a[i]); for(int i = 0; i < m; i++) scanf("%d", &b[i]); for(int i = 0; i < n; i++) { nx[a[i]] = i; } memset(vst, 0, sizeof(bool) * maxn); memset(num_a, 0, sizeof(num_a)); memset(num_b, 0, sizeof(num_b)); for(int i = 0; i < n; i++) { if(!vst[i]) { int now = nx[i]; int cnt = 1; vst[now] = 1; while(now != i){ now = nx[now]; vst[now] = 1; cnt++; } num_a[cnt]++; } } memset(vst, 0, sizeof(vst)); for(int i = 0; i < m; i++) { if(!vst[i]) { int now = b[i]; int cnt = 1; vst[now] = 1; while(now != i){ now = b[now]; cnt++; vst[now] = 1; } num_b[cnt]++; } } ll ans = 1; for(int i = 1; i <= n; i++) { if(num_a[i]) { int Max = sqrt(i + 0.5); ll tmp = 0; for(int j = 1; j <= Max; j++) { if(i % j == 0) { tmp += (j * num_b[j]) % mod; if(j * j != i) tmp += ((i / j) * num_b[i / j]) % mod; } } for(int j = 0; j < num_a[i]; j++) ans = ans * tmp % mod; } } printf("Case #%d: %I64d\n", Case++, (ans % mod)); } return 0; }
相关文章推荐
- 2017多校第一场1006 function(HDU6038)
- 2017年多校赛第一场 1011 KazaQ's Socks(找规律)
- 2017多校联合第一场 1006题 hdu 6038 Function 循环节
- 2017年多校赛第九场 1006 Senior Pan(dijkstra套路题)
- 2017年多校赛第一场 1001 Add More Zero(逻辑思维)
- 2017多校第一场 1006 Function
- 多校第一场 1001 hdu 5288 OO’s Sequence(枚举)
- 2015多校赛第一场
- 多校第六场 1006 hdu 5358 First One(枚举)
- hdu 5723 Abandoned country 2016 多校赛第一场
- HDU 5723 2016多校赛第一场 最小生成树+记忆化搜索
- 2017年ZJUT校赛-Problem A: 画图游戏——博弈论
- 南华大学ACM个人连续第一场 E.Function
- 2015 多校赛 第五场 1006 (hdu 5348)
- hdu4728 PowMod(2016多校第一场1006)
- 2017年多校赛第九场 1005 FFF at Valentine(缩点+拓扑排序)
- 2017年ZJUT校赛-Problem B: 平方2——树状数组
- 2015多校赛第一场
- 2016第一场多校赛
- 【牛客网 2017年校招模拟笔试(第一场)】 序列和