hdu6038
hdu6038
分析
求函数 \(f\) 的构成方案,\(f\) 确定下来后,\(f\) 和 \(b\) 的值也是一一对应的了( \(f(i)=b_{f(a_i)}\) ),观察 \(a\) 数组,代入 \(f\) 函数,存在循环节,比如 \(a[0] = 1, a[1] = 0\),那么循环节长度为 2,代入后,\(f(0)=b_{f(1)}, f(1)=b_{f(0)}\),也能形成类似的循环节,正好是前面循环节的长度(后面我们直接去考虑对应 \(a\) 数组的循环节就好了)。观察 \(b\) 数组,同样会存在一些循环节,如果 \(b\) 数组中有一个长度为 \(1\) 的和一个长度为 \(2\) 的循环节, \(a\) 数组中有一个长度为 \(2\) 的循环节,那么显然给 \(a\) 数组这个长度为 \(2\) 的循环节分别提供一种和两种方案(因为是循环,可以看做是一个环,那么可以调整所有数的位置,保持每个数的相对位置不变,所以长度 \(2\) 的能提供两种)。所有在 \(b\) 数组的循环节且长度是 \(a\) 中的某个循环节长度的因子,都能增加 \(a\) 中这个循环节的方案数,最后将 \(a\) 中所有循环节的方案数相乘即可。(把样例画画找下规律......)
code
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<algorithm>
#include<iostream>
typedef long long ll;
const ll MAXN = 1e5 + 10;
const ll INF = 1e8;
const ll MOD = 1e9 + 7;
using namespace std;
int kase = 1;
int a[MAXN], b[MAXN];
int vis[MAXN];
int loop_b[MAXN];
int loop_a[MAXN];
int main() {
int n, m;
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_b, 0, sizeof loop_b);
memset(loop_a, 0, sizeof loop_a);
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]++;
}
}
memset(vis, 0, sizeof vis);
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]++;
}
}
ll ans = 1;
for(int i = 1; i <= n; i++) {
ll res = 0;
for(int j = 1; j * j <= i; j++) { // 这里可以预处理一波
if(i % j == 0) {
int k = j;
res += loop_b[j] * j;
if(j * j != i) {
k = i / j;
res += loop_b[k] * k;
}
}
}
int C = loop_a[i];
while(C--) {
ans = (ans * res) % MOD;
}
}
printf("Case #%d: %lld\n", kase++, ans);
}
return 0;
}
hdu6038的更多相关文章
- hdu6038 Function 函数映射
/** 题目:hdu6038 Function 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6038 题意:给定一个a排列[0,n-1],一个b排列[0, ...
- hdu6038[找规律+循环节] 2017多校1
/*hdu6038[找规律+循环节] 2017多校1*/ #include<bits/stdc++.h> using namespace std; typedef long long LL ...
- 2017多校第一套&&hdu6038 思维 数学
链接 http://acm.hdu.edu.cn/showproblem.php?pid=6038 题意: 给你一个a序列,代表0到n-1的排列:一个b序列代表0到m-1的排列.问你可以找出多少种函 ...
- 【置换群】【枚举约数】hdu6038 Function
把b数组的所有置换群求出来,用数组记录一下每个大小所出现的次数. 然后求a的置换群,对每个置换群求能被其整除的b的置换群的大小总和(只有这些才能满足构造出一个f,且不自相矛盾),然后把它们全都乘起来就 ...
- HDU6038:Function(循环群/节+找公式)
传送门 题意 给出一个\(0\sim n-1\)的排列a,一个\(0\sim {m-1}\)的排列b,询问满足\[f(i)=b_{f(a_i)}~~(0\le i\le n-1)\]的函数的个数 分析 ...
- HDU-6038 Function 思维+循环节
解法:这道题很有意思,值得一做和细细思考. 首先是我们要观察这个映射公式,他的实质是什么?其实就是b到a的循环映射,这是因为a数列和b数列都是0-n-1的排列,意味着每个数都是唯一的,那么ab的这个循 ...
- 排列+函数映射——hdu6038好题
/* 引理:[0,n-1]的排列,i向a[i]连边,那么每个数必定在一个环中 所以数组a可以分割成一些环,数组b也可以分割成一些环 先讨论a的一个环 a[a1]=a2 a[a2]=a3 a[a3]=a ...
- 「2017 Multi-University Training Contest 1」2017多校训练1
1001 Add More Zero(签到题) 题目链接 HDU6033 Add More Zero 找出最大的k,使得\(2^m-1\ge 10^k\). 直接取log,-1可以忽略不计. #inc ...
随机推荐
- 《Cracking the Coding Interview》——第2章:链表——题目2
2014-03-18 02:24 题目:给定一个单链表,找出倒数第K个节点. 解法:让一个指针先走K步,然后俩指针一起走到尽头.当然也可以先走到尽头数出链表的长度,然后第二次少走K步.其实耗费的工夫是 ...
- 云计算之路-阿里云上:SLB引起的https访问速度慢问题
自从我们在阿里云SLB上部署了https之后(详见在SLB上部署https遇到的问题及解决方法),陆续有园友向我们反馈登录时速度很慢(登录时是通过https访问),有些园友甚至无法访问登录页面. 而我 ...
- (原)DirectX11 深度测试(有点另类)
(问到自己清楚就可) @Author: 白袍小道 @说明:转载随缘,评论随缘,询问建议看书和源码会得到更准确的答案 深度测试的来源.目的.做法 一.问题询问 我们带着一些问题去浏览一番 1.深度测试发 ...
- oracle 隔离级别、事务怎么开始的以及如何查看数据库采用字符集
把一下语句全部粘贴至控制台运行后可以查看oracle 隔离级别 declare trans_id ); begin trans_id := dbms_transaction.local_transac ...
- js万年历
首先,注意: 1.延迟执行 window.setTimeout( , ) 里面的时间是以毫秒计算的 2.间隔执行 window.setInterval( , ...
- KindleEditor insertfile初始化多个
KindEditor.ready(function (K) { var editor = K.editor({ allowFileManager: true }); K('#insertfile'). ...
- struct&&class 空的大小
#include using namespace std; class ClassA { }; class ClassB { private: int b; }; class ClassC : pub ...
- struts框架搭建
struts是开源框架.使用Struts的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间.如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,struts是一个不错的 ...
- 没有外网情况下linux安装mysql
首先linux要使用局域网 环境要求:局域网, windows系统, linux系统, mysql安装包mysql.tar.gz 注意:32位操作系统用32位安装包,64位系统用64位安装包,不 ...
- CentOS7 安装 webgoat 7.1 简介
CentOS7 安装 webgoat 7.1 简介 webgoat 所需文件准备: 操作系统版本:CentOS 7.3 1: 在Linux上安装Openjdk >= 1.8 2: 上传文件至 L ...