We have a sequence of $N$ positive integers: $A_1,A_2,\cdots,A_N$. You are to rearrange these integers into another sequence $x_1,x_2,\cdots,x_N$, where $x$ must satisfy the following condition:
Determine whether it is possible to form a sequence $x$ satisfying the condition, and show one such sequence if it is possible.
Input is given from Standard Input in the following format:
$N$ $A_1$ $A_2$ $\cdots$ $A_N$
If it is possible to form a sequence $x$ satisfying the condition, print your answer in the following format:
Yes $x_1$ $x_2$ $\cdots$ $x_N$
If it is impossible, print No
.
3 3 4 6
Yes 3 6 4
For $x=(3,6,4)$, we have:
Here, $y_1
3 2 3 6
No
No permutation of $A$ would satisfy the condition.
10 922513 346046618969 3247317977078471 4638516664311857 18332844097865861 81706734998806133 116282391418772039 134115264093375553 156087536381939527 255595307440611247
Yes 922513 346046618969 116282391418772039 81706734998806133 255595307440611247 156087536381939527 134115264093375553 18332844097865861 3247317977078471 4638516664311857
巧妙地,考虑倒着构造整个序列。
想一下如何选出一个可以排在最后的数,当且仅当他存在某一个质因子的次数是严格最大的。
可以先用 Pollard-Pho 分解出来判断。
每次选一个可以放在最后的元素,不会使本来可以放的数变成不能放。
但是真的要 Pollard-Pho 吗?
枚举 1 0 6 10^6 106 以内的数进行分解,那么还没分解出来的要不是两个大质数相乘,要不是一个质数。
对于两个大质数的情况,枚举其他的数,取gcd,如果取出来不是 1 我们就分解出来了,否则可以把这个数当成一个数,不影响性质。
#include
using namespace std;
const int N=105,M=N*30;
typedef long long LL;
int p[N][M],c,n,vs[N],st[N];
LL a[N],to[M],b[N];
map<LL,LL>v;
multiset<int>s[M];
LL gcd(LL x,LL y)
{
if(!y)
return x;
return gcd(y,x%y);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",a+i),b[i]=a[i];
for(int j=2;j<=1000000;j++)
{
if(a[i]%j==0)
{
if(!v[j])
to[++c]=j,v[j]=c;
while(a[i]%j==0)
a[i]/=j,p[i][v[j]]++;
}
}
}
for(int i=1;i<=n;i++)
{
if(a[i]==1)
continue;
int fl=0;
for(int j=1;j<=n;j++)
{
LL d=gcd(a[i],a[j]);
if(d^a[i]&&d^1)
{
if(!v[d])
v[d]=++c;
if(!v[a[i]/d])
to[++c]=a[i]/d,v[a[i]/d]=c;
++p[i][v[d]],++p[i][v[a[i]/d]];
fl=1,j=n;
}
}
if(!fl)
{
if(!v[a[i]])
to[++c]=a[i],v[a[i]]=c;
p[i][v[a[i]]]++;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=c;j++)
s[j].insert(p[i][j]);
// for(int i=1;i<=n;i++)
// {
// printf("%lld ",b[i]);
// for(int j=1;j<=c;j++)
// printf("%lld %d\n",to[j],p[i][j]);
// puts("");
//
// }
for(int i=1;i<=n;i++)
{
int pf=0;
for(int j=1;j<=n;j++)
{
if(vs[j])
continue;
int fl=0;
for(int k=1;k<=c;k++)
if(s[k].size()==1||(*(--s[k].end())==p[j][k]&&(*--s[k].end())^(*(--(--s[k].end())))))
fl=1,vs[j]=1,st[i]=j,k=c,pf=1;
if(fl)
{
for(int k=1;k<=c;k++)
s[k].erase(s[k].lower_bound(p[j][k]));
j=n;
}
}
if(!pf)
return puts("No"),0;
}
puts("Yes");
for(int i=n;i>=1;i--)
printf("%lld ",b[st[i]]);
}