正题
题目链接:https://www.luogu.com.cn/problem/CF1419E
题目大意
nnn的所有约数排成一个圈,求一个顺序使得相邻的互质的数最少。
解题思路
质因数分解后,我们考虑每个质因数之间填什么。对于两个质因数a,ba,ba,b。显然a∗ba*ba∗b也是nnn的约数,也就是aaa与bbb之间必定有一个可以填进去的数。
显然对于每个质因数也是如此,一般的,我们对于分解出来的pcp^cpc和p′c′p'^{c'}p′c′我们可以在将pk(1≤k≤c)p^k(1\leq k\leq c)pk(1≤k≤c)都填在一起,然后在之后填上具有ppp和p′p'p′因子的所有没有填过的约数。特别的,nnn要填在最后面(拼接第一个和最后一个质因子)。
然后对于只有两个不同的质因子a,ba,ba,b的数,我们不难发现a∗b=na*b=na∗b=n也就是nnn没有办法填在最后,此时互质数为111,其他都为000
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2e5+10;
ll T,n,p[N],v[N],cnt;
void dfs(ll dep,ll x){if(x==n||dep>cnt&&x==1)return;if(dep>cnt){printf("%lld ",x);return;}ll w=p[dep],z=1;if(x==1){for(ll i=1;i<=v[dep];i++)z*=w;for(ll i=v[dep];i>=0;i--)dfs(dep+1,x*z),z/=w;}else{for(ll i=0;i<=v[dep];i++)dfs(dep+1,x*z),z*=w;}
}
int main()
{scanf("%lld",&T);while(T--){scanf("%lld",&n);ll x=n,z=0;cnt=0;for(ll i=2;i*i<=x;i++){if(x%i==0){p[++cnt]=i;while(x%i==0)x/=i,v[cnt]++,z++;}}if(x!=1){bool flag=1;for(ll i=1;i<=cnt;i++)if(p[i]==x){flag=0;break;}if(flag){p[++cnt]=x;v[cnt]++;z++;}}dfs(1,1);printf("%lld\n",n);if(z==2&&cnt==2)printf("1\n");else printf("0\n");for(ll i=1;i<=cnt;i++)v[i]=0;}
}