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. 【MySQL】MySQL(四)存储引擎、索引、锁、集群

    MySQL存储引擎 MySQL体系结构 体系结构的概念 任何一套系统当中,每个部件都能起到一定的作用! MySQL的体系结构 体系结构详解 客户端连接 支持接口:支持的客户端连接,例如C.Java.P ...

  2. springcloud (一)系统架构演变之路

    演变过程 从传统架构(单点应用)→分布式架构(以项目进行拆分)→SOA架构(面向服务架构)→微服务架构 1 传统架构 其实就是ssh架构或者ssm架构,属于单点应用,把整个开发业务模块都会在一个项目中 ...

  3. pagelayout在py中的引用不支持size_hint和pos_hint

    from kivy.uix.pagelayout import PageLayout from kivy.uix.button import Button from kivy.app import A ...

  4. UltraSoft - Alpha - Scrum Meeting 5

    Date: Apr q9th, 2020. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM 统筹个人进度,协助推进进度 辅助前后端连接工作 刘zh 前端 完 ...

  5. [Beta]the Agiles Scrum Meeting 5

    会议时间:2020.5.19 20:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 为评测机增加更多评测指标 评测部分增加更多评测指标 tq 为评测机增加更多评测指标 ...

  6. IC封装的热特性

    ΘJA是结到周围环境的热阻,单位是°C/W.周围环境通常被看作热"地"点.ΘJA取决于IC封装.电路板.空气流通.辐射和系统特性,通常辐射的影响可以忽略.ΘJA专指自然条件下(没有 ...

  7. Spark面试题整理(三)

    1.为什么要进行序列化序列化? 可以减少数据的体积,减少存储空间,高效存储和传输数据,不好的是使用的时候要反序列化,非常消耗CPU. 2.Yarn中的container是由谁负责销毁的,在Hadoop ...

  8. (继承)Program2.1

    覆盖和重写的意思是一样?结果是一样的 例如: 1 class Parent: # 定义父类 2 def myMethod(self): 3 print('调用父类方法') 4 5 6 class Ch ...

  9. Python matplotlib pylot和pylab的区别

    matplotlib是Python中强大的绘图库. matplotlib下pyplot和pylab均可以绘图. 具体来说两者的区别 pyplot 方便快速绘制matplotlib通过pyplot模块提 ...

  10. 访问单个结点的删除 牛客网 程序员面试金典 C++ Python

    访问单个结点的删除 牛客网 程序员面试金典 C++ Python 题目描述 实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点. 给定待删除的节点,请执行删除操作,若该节点为尾节点,返回f ...