序列排序Ⅱ

846 字
4 分钟
序列排序Ⅱ

原题题面

描述

ldz 交给你了一个 1~n 的排列,当某两个相邻的数字满足互质时,则可以交换这两个数字,请问你进行若干次交换后,能否将这个排列变为严格递增的。(即 1, 2, 3, 4... , n-1, n)

两个数字互质的定义:若两个数字的最大公约数为 1 时,即认为这两个数字互质。

输入

输入第一行包含一个正整数 n(1≤n≤105)。

接下来一行包含由空格隔开的 nn 个正整数,第i个整数记为 a_iai​,保证每个数字仅出现一次,且满足 (1≤a_i≤n)(1≤ai​≤n)。

输出

输出 "Yes" 代表可以使得序列有序,否则输出 "No"。(不要输出引号)

输入样例 1 

8
1 2 8 4 5 6 7 3

输出样例 1

No

提示

由于只能交换相邻的数字,所以无法使得排列递增。

解析

对于任意两个数……

让我们以样例的这组序列为例:1 2 8 4 5 6 7 3

随便挑出两个数字,如8和6。显然,这8在前而6在后。也就是说,不管8和6如何运动,最终将会靠在一起并交换位置。显然,此时8和6并不互质,所以6无法移动位置至8前面。

理清思路

如上所述,若是两个数ab满足以下3个条件:

  1. a>b;
  2. a在b前;
  3. a和b不互质。

那么,如果在一个序列中只要有任意的如是两个数,该序列就无法满足题意。

基本实现

如果只根据以上思路,把序列双重循环地遍历,复杂度就到了O(n²),显然会超时。然而,如果把不互质的所有数拎出来,就满足了第3个条件;另外要依次取出,就满足了第2个条件;最后只需对与这一个被拎出来的子序列进行遍历,如果发现有任意的a>b,即满足了第1个条件,那么该序列就无法满足题意,输出No

示例代码

#include
    

using namespace std; const int maxn=100005; int n,a[maxn]; vector G[maxn]; int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; for(int j=2;j*j<=a[i];j++){ if(a[i]%j==0){ G[j].push_back(a[i]); G[a[i]/j].push_back(a[i]); } } } for(int i=2;i<=n;i++){ for(int j=1;j <g[i].size();j++){ if(g[i][j]<g[i][j-1]){="" cout<<“no”;="" return="" 0;="" }="" cout<<“yes”;="" }<="" ode=""></g[i].size();j++){>

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
序列排序Ⅱ
https://www.0x3f.foo/posts/序列排序ⅱ/
作者
Dignite
发布于
2021-03-29
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Dignite
When nothing goes right, go left.
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
站点统计
文章
146
分类
5
标签
271
总字数
314,753
运行时长
0
最后活动
0 天前

目录