Codeforces 题面传送门 & 洛谷题面传送门

u1s1 感觉这个 D1F 比某道 jxd 作业里的 D1F 质量高多了啊,为啥这场的 D 进了 jxd 作业而这道题没进/yun

首先这题肯定有个结论对吧,那么我们就先尝试猜一下什么样的排列符合条件,也就是先考虑这题 \(a_i\)​​ 全是 \(-1\)​​ 的情况怎么做,那么通过观察可以发现,由于判定两个数是否互质的过程中只需要考虑它们的质因子集合即可,因此可以发现如果两个数包含的质因子集合完全相同,那么它们显然是可以互换的,因此假设第 \(i\)​​ 种质因子集合有 \(c_i\)​​ 个数,对于全 \(-1\)​​ 的情况贡献应乘上 \(\prod c_i!\)​​。没了吗?手玩一下样例发现对于 \(n=5\)​​ 的情况 \(3,5\)​​ 也可以交换,我们不妨来分析一波,对于 \(n=5\)​​ 的情况 \(3,5\)​​ 满足 \(\lfloor\dfrac{5}{3}\rfloor=\lfloor\dfrac{5}{5}\rfloor\)​​,也就是说我们可以将 \(5\)​​ 的倍数与 \(3\)​​ 的倍数整体互换,类似地,对于两个质数 \(p_i,p_j\)​​,如果它们满足 \(\lfloor\dfrac{n}{p_i}\rfloor=\lfloor\dfrac{n}{p_j}\rfloor\)​​,那么我们对于 \(k\in[1,\lfloor\dfrac{n}{p_i}\rfloor]\)​​,将 \(p_i·k\)​​ 出现的位置与 \(p_j·k\)​​ 出现的问题交换,不难证明交换前任意两个位置是否互质的情况相同,因此如果交换前满足条件,交换后也满足条件,因此如果再记 \(C_i\)​ 表示有多少个质数 \(p\)​ 满足 \(\lfloor\dfrac{n}{p}\rfloor=i\)​,那么答案还要再乘上 \(\prod C_i!\)​。这样已经是充要条件了吗?没错,打个表可以发现所有符合要求都符合上述两个条件。

然后我打表只看出了第一个结论,然后第二个结论以为 \(>\dfrac{n}{2}\) 的质数也可视作相同,然后就愉快地 WA 12 了

然后考虑存在一个 \(a_i\) 固定的情况,显然对于这样的情况,我们还要找排列中的数在换来换去的过程中,有没有什么量是不变的,显然我们的操作只可能是交换两个质数,不会改变每个位置的 \(a_i\) 的质因子个数,因此如果 \(a_i\) 质因子个数不等于 \(i\) 质因子个数就直接 \(-1\)。同理交换前后,是不改变 \(n\) 除以对应质因子下取整的值的,因此如果我们发现 \(i\) 与 \(a_i\) 中,\(n\) 除以对应质因子下取整的值不同,那也可以直接 \(-1\)。那还有没有需要 \(-1\) 的情况呢?不难发现如果存在一个质因子已经被钦定要映射到别的质因子上,而在 \(i\) 与 \(a_i\) 中这种映射关系出现了冲突,那么也应是 \(-1\)。这里有一个投机取巧(bushi)的技巧,就是显然能够交换的质因子只可能 \(>\sqrt{n}\),而一个 \(\le n\) 的数中最多只有一个 \(>\sqrt{n}\)​ 的质因子,因此对于这种情况我们只用检验最大的质因子是否满足条件即可。如果不存在上述三种情况那肯定是有解的,不同于 \(a_i\) 全是 \(-1\) 的情况的一点是,如果我们发现 \(a_i\ne 0\),那么我们就找出 \(a_i\) 的质因子集合,然后令对应的 \(c_i\) 减 \(1\),然后如果我们找出了一对质因子的映射关系,就将对应的 \(C_i\) 减 \(1\),然后还是输出 \(\prod c_i!·\prod C_i!\)​ 即可。

时间复杂度 \(\sum\limits_{i=1}^n\omega(i)<\mathcal O(7·n)=\mathcal O(n)\)

const int MAXN=1e6;
const int MOD=1e9+7;
int pr[MAXN/8+5],prcnt=0,mnp[MAXN+5];
bitset<MAXN+5> vis;
void sieve(int n){
for(int i=2;i<=n;i++){
if(!vis[i]) pr[++prcnt]=i,mnp[i]=i;
for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
vis[pr[j]*i]=1;mnp[pr[j]*i]=pr[j];
if(i%pr[j]==0) break;
}
}
}
int n,a[MAXN+5],fac[MAXN+5],mul[MAXN+5],num[MAXN+5];
int to1[MAXN+5],to2[MAXN+5];
int c1[MAXN+5],c2[MAXN+5];
vector<int> pf[MAXN+5];
int main(){
scanf("%d",&n);sieve(n);
for(int i=2;i<=n;i++){
int tmp=i;mul[i]=1;
while(tmp^1){
int p=mnp[tmp];
while(tmp%p==0) tmp/=p;
pf[i].pb(p);mul[i]*=p;
} c1[mul[i]]++;
} pf[1].pb(1);num[1]=1;c2[1]++;
for(int i=1;i<=prcnt;i++) num[pr[i]]=n/pr[i],c2[num[pr[i]]]++;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) if(a[i]){
if(pf[i].size()!=pf[a[i]].size()) return puts("0"),0;
for(int j=0;j+1<pf[i].size();j++) if(pf[i][j]!=pf[i][j]) return puts("0"),0;
int x=pf[i].back(),y=pf[a[i]].back();
if(num[x]!=num[y]) return puts("0"),0;
if(to1[x]&&to1[x]!=y) return puts("0"),0;
if(to2[y]&&to2[y]!=x) return puts("0"),0;
if(!to1[x]&&!to2[y]) c2[num[x]]--;
to1[x]=y;to2[y]=x;c1[mul[a[i]]]--;
} int res=1;
for(int i=(fac[0]=1);i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD;
for(int i=1;i<=n;i++) res=1ll*res*fac[c1[i]]%MOD;
for(int i=1;i<=n;i++) res=1ll*res*fac[c2[i]]%MOD;
printf("%d\n",res);
return 0;
}

Codeforces 698F - Coprime Permutation(找性质)的更多相关文章

  1. Codeforces 1442D - Sum(找性质+分治+背包)

    Codeforces 题面传送门 & 洛谷题面传送门 智商掉线/ll 本来以为是个奇怪的反悔贪心,然后便一直往反悔贪心的方向想就没想出来,看了题解才发现是个 nb 结论题. Conclusio ...

  2. [Codeforces 1208D]Restore Permutation (树状数组)

    [Codeforces 1208D]Restore Permutation (树状数组) 题面 有一个长度为n的排列a.对于每个元素i,\(s_i\)表示\(\sum_{j=1,a_j<a_i} ...

  3. Atcoder Grand Contest 008 E - Next or Nextnext(乱搞+找性质)

    Atcoder 题面传送门 & 洛谷题面传送门 震惊,我竟然能独立切掉 AGC E 难度的思维题! hb:nb tea 一道 感觉此题就是找性质,找性质,再找性质( 首先看到排列有关的问题,我 ...

  4. Codeforces 1264F - Beautiful Fibonacci Problem(猜结论+找性质)

    Codeforces 题面传送门 & 洛谷题面传送门 一道名副其实(beautiful)的结论题. 首先看到这道设问方式我们可以很自然地想到套用斐波那契数列的恒等式,注意到这里涉及到 \(F_ ...

  5. Codeforces 1413F - Roads and Ramen(树的直径+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 其实是一道还算一般的题罢--大概是最近刷长链剖分,被某道长链剖分与直径结合的题爆踩之后就点开了这题. 本题的难点就在于看出一个性质:最长路 ...

  6. Codeforces 526G - Spiders Evil Plan(长链剖分+直径+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 %%%%% 这题也太神了吧 storz 57072 %%%%% 首先容易注意到我们选择的这 \(y\) 条路径的端点一定是叶子节点,否则我 ...

  7. Codeforces 1188E - Problem from Red Panda(找性质+组合数学)

    Codeforces 题面传送门 & 洛谷题面传送门 咦,题解搬运人竟是我? 一道很毒的计数题. 先转化下题意,每一次操作我们可以视作选择一种颜色并将其出现次数 \(+k\),之后将所有颜色的 ...

  8. Codeforces 1383C - String Transformation 2(找性质+状压 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神奇的强迫症效应,一场只要 AC 了 A.B.D.E.F,就一定会把 C 补掉( 感觉这个 C 难度比 D 难度高啊-- 首先考虑对问题进 ...

  9. Codeforces 1067E - Random Forest Rank(找性质+树形 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 一道不知道能不能算上自己 AC 的 D1E(?) 挺有意思的结论题,结论倒是自己猜出来了,可根本不会证( 开始搬运题解 ing: 碰到这样 ...

随机推荐

  1. 寻找写代码感觉(八)之SpringBoot过滤器的使用

    一.什么是过滤器? 过滤器是对数据进行过滤,预处理过程,当我们访问网站时,有时候会发布一些敏感信息,发完以后有的会用*替代,还有就是登陆权限控制等,一个资源,没有经过授权,肯定是不能让用户随便访问的, ...

  2. 软工博客之关于CSDN的移动端软件测评

    关于CSDN的移动端软件测评 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 软件测评作业 我在这个课程的目标 不求变强,只求做好,成为一颗有用的 ...

  3. logstash处理多行日志-处理java堆栈日志

    logstash处理多行日志-处理java堆栈日志 一.背景 二.需求 三.实现思路 1.分析日志 2.实现,编写pipeline文件 四.注意事项 五.参考文档 一.背景 在我们的java程序中,经 ...

  4. 攻防世界 杂项 12.Training-Stegano-1

    题目描述: 这是我能想到的最基础的图片隐写术.啊这 题目分析: 最初还以为直接右击属性查看呢 然后用notepad++看看,一团乱码,结果在最后发现了passwd, 然后这就是flag:stegano ...

  5. linux 内核源代码情景分析——linux 内核源代码中的C语言代码

    linux 内核的主体是以GNU的C语言编写的,GNU为此提供了编译工具gcc.GNU对C语言本身作了不少扩充. 1) gcc 从 C++ 语言中吸收了"inline"和" ...

  6. js实现日期格式化封装--八种

    封装一个momentTime.js文件,包含8种格式. 需要传两个参数: 时间戳:stamp 格式化的类型:type, 日期补零的方法用到es6语法中的padStart(length,'字符'): 第 ...

  7. IDEA免费激活至2099年教程,亲测可用

    申明,本教程 Intellij IDEA 最新版激活教程,激活码均收集与网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除.如条件允许,建议大家购买正版. 以下是本人免费激活到 2099 年的 ...

  8. Get value from agent failed: cannot connect to [[127.0.0.1]:10050]: [111] Connection refused

    zabbix 监控连接失败 1.查看配置文件端口,server端口10051开启正常,agent端10050开启正常 2.查看/var/log/zabbix/zabbix_server.log./va ...

  9. 剖析虚幻渲染体系(12)- 移动端专题Part 1(UE移动端渲染分析)

    目录 12.1 本篇概述 12.1.1 移动设备的特点 12.2 UE移动端渲染特性 12.2.1 Feature Level 12.2.2 Deferred Shading 12.2.3 Groun ...

  10. linux网络编程 IO多路复用 select epoll

    本文以我的小型聊天室为例,对于服务器端的代码,做了三次改进,我将分别介绍阻塞式IO,select,epoll . 一:阻塞式IO 对于聊天室这种程序,我们最容易想到的是在服务器端accept之后,然后 ...