【hdu 6038】Function
【Link】:http://codeforces.com/contest/834/problem/C
【Description】
给你两个排列a和b;
a排列的长度为n,b排列的长度为m;
a∈[0..n-1],b∈[0..m-1];
然后让你求一个函数f[i];
f[i]的定义域为0..n-1,值域为0..m-1
同时使得对于任意f[i],i∈[0..n-1];
f(i)=bf(a[i])成立;
【Solution】
原始可以递推一下;
f(i)=bf(ai)=bbf(aai)
则可以一直写下去f[i]=bbbbbf(aaaaa[i]);
注意到a是一个排列;
最后肯定能形成一个环,则aaaaa..a[i]肯定又能变回i
则
f(i)=b⋯bf(i)l times b
(这里L是第一次回到i的L);
这里的含义其实就相当于f[i]是一个x
要使得
x=b....bx
而b也是一个排列;
则也肯定有循环节;
这里从x开始的b数组的循环节长度一定得是上面的a的循环节的长度L的因子;
不然就不能在L次b之后回到x了;
于是,
在a数组里找循环节的长度,在b数组中也找循环节的长度;
看看有多少个长度在a中有,且b数组中,有它的因子长度的循环节;
直接累加因子循环节长度到temp中;
然后累乘所有temp即可;
根据上面的形式,每个a循环节中的某一个位置,f只要确定了,其他该循环节中的f值也就确定了,然后那个位置有temp种选择;就是因子循环节中任意一个b[i]都可以;
找因子的时候,需要做些优化;
不然可能退成O(n2)的复杂度;
先枚举a数组有哪些循环节,长度为i;
然后用O(i12)复杂度枚举它可能的因子,(j是则n/j也是)
看看在b中有没有这样长度的;
【NumberOf WA】
0
【Reviw】
求因子的思想很好.
【Code】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5;
const int MOD = 1e9+7;
int n,m;
int a[N+10],b[N+10],cnta[N+10],cntb[N+10];
bool flag[N+10];
main(){
int kk = 0;
while (~scanf("%lld%lld",&n,&m)){
for (int i = 1;i <= n;i++){
scanf("%lld",&a[i]);
a[i]++;
}
for (int i = 1;i <= m;i++){
scanf("%lld",&b[i]);
b[i]++;
}
memset(cnta,0,sizeof cnta);
memset(cntb,0,sizeof cntb);
memset(flag,0,sizeof flag);
for (int i = 1;i <= m;i++)
if (!flag[i]){
int x = i,num = 0;
while (!flag[x]){
flag[x] = 1;
num++;
x = b[x];
}
cntb[num]++;
}
memset(flag,0,sizeof flag);
for (int i = 1;i <= n;i++)
if (!flag[i]){
int x = i,num = 0;
while (!flag[x]){
flag[x] = 1;
num++;
x = a[x];
}
cnta[num]++;
}
int ans = 1;
for (int i = 1;i <= n;i++)
if (cnta[i]>0){
int temp = 0;
for (int j = 1;j*j <= i;j++)
if (i%j==0){
temp = (temp + j*cntb[j])%MOD;
if (j != i/j)
temp = (temp + (i/j)*cntb[i/j])%MOD;
}
while (cnta[i]--){
ans = (ans*temp)%MOD;
}
}
printf("Case #%lld: %lld\n",++kk,ans);
}
return 0;
}
【hdu 6038】Function的更多相关文章
- 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题
[HDU 3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...
- 【HDU 5647】DZY Loves Connecting(树DP)
pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...
- -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】
[把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...
- 【HDU 2196】 Computer(树的直径)
[HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...
- 【HDU 2196】 Computer (树形DP)
[HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...
- 【HDU 5145】 NPY and girls(组合+莫队)
pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...
- 【hdu 1043】Eight
[题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...
- 【HDU 3068】 最长回文
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...
- 【HDU 4699】 Editor
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4699 [算法] 维护两个栈,一个栈放光标之前的数,另外一个放光标之后的数 在维护栈的同时求最大前缀 ...
随机推荐
- mysql优化篇之表分区
当表的数据量达到一定数量时(如单个.myd文件都达到10G,myd 是mysql的数据文件),这时候读取起来必然效率很低. 1.从业务角度可以解决(分表) ...
- 洛谷3857 [TJOI2008]彩灯
题目描述 已知一组彩灯是由一排N个独立的灯泡构成的,并且有M个开关控制它们.从数学的角度看,这一排彩灯的任何一个彩灯只有亮与不亮两个状态,所以共有2N个样式.由于技术上的问题,Peter设计的每个开关 ...
- docker操作大全
docker 常用操作方法 查看docker版本docker version 搜索镜像docker serach 镜像名称 拉去镜像docker pull 镜像名称 查看本地镜像仓库信息docker ...
- new期间的异常
new包含两步,调用operator new申请空间,以及调用构造函数. 如果第一步结束之后,第二步发生异常,需要归还第一步的空间. 编译器帮我们做了这件事情,并且会调用对应的delete. 另外 n ...
- eclipse下Tomcat7.0启动奔溃问题
好久没用Eclipse了,如今上班这家公司正好用到了,完后用Tomcat启动项目一直报一个错,例如以下图 错误代码例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...
- POJ 1258 Agri-Net (最小生成树+Prim)
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39820 Accepted: 16192 Descri ...
- Node.js的helloworld 程序
用文本编辑器.如npp,键入例如以下代码.存储成hello.js console.log('hello') console.log('hello %s->%d','jeapedu', 19418 ...
- java内部类的初始化
public class InnerClassTest { /** * @param args */ public static void main(String[] args) { // TODO ...
- HTML <button> 标签
HTML <button> 标签 目标 实现点击button跳转到一个新的界面 参考文档 实例 以下代码标记一个按钮: <button type="button" ...
- 洛谷P2415 集合求和
题目描述 给定一个集合s(集合元素数量<=30),求出此集合所有子集元素之和. 输入输出格式 输入格式: 集合中的元素(元素<=1000) 输出格式: 和 输入输出样例 输入样例#1: 2 ...