传送门
找到(n)的两个约数(p_1, p_2),使得(gcd(p_1+p_2, n) = 1)
gcd的一些性质
- (gcd(a, b) = gcd(a, b - a) = gcd(b, a % b))
- 若(gcd(a, b) = 1),则(gcd(a, b) = gcd(a + b, a * b))
- (gcd(a, b) = gcd(a + b, b))
- 若(gcd(a, c) = 1), 则(gcd(a, bc) = gcd(a, b))
根据唯一分解定理,把(n = p_1^{a_1} p_2^{a_2}...p_k^{a_k})分解为
(p_1^{a_1})和(p_2^{a_2}...p_k^{a_k}),那么就利用性质2即可。
直接暴力跑会tie,那么就先欧拉筛
int cal(int n){
if(!vis[n]) return -1;
int ans = 1;
for(int i = 1; pri[i] * pri[i] <= n && i <= tot; i++) {
if(n % pri[i] == 0) {
while(n % pri[i] == 0) n /= pri[i], ans *= pri[i];
break;
}
}
if(n > 1 && ans > 1) return ans;
else return -1;
}
int x[N], y[N], a[N];
void solve(int kase){
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) {
x[i] = cal(a[i]);
if(x[i] == -1) y[i] = -1;
else y[i] = a[i] / x[i];
}
for(int i = 1; i <= n; i++)
printf("%d%c", x[i], "
"[i == n]);
for(int i = 1; i <= n; i++)
printf("%d%c", y[i], "
"[i == n]);
}