题意
(d_1, d_2)是 a 的因子, 找到 gcd((d_ 1 + d_2), a) = 1
题解
gcd(x, y) = gcd(x + y, y) = gcd(x, y + x) = gcd(x, (y^n)) = gcd((x^n), y) = gcd(x + y, x * y) = 1;
证明:
辗转相除法的逆用 gcd(x, y) = gcd(x - y, y) = gcd(x + y, y) 没啥区别
设 x = ky + r(0 < r < x)
gcd(x, y) = gcd(x, y * (y ^ {n - 1})) = gcd(ky + r, (y^{n-1}) * y + 0) = 1
设 x = ky + r(0 < r < x)
gcd(x, y) = gcd(x + y, y) = gcd((k + 1)y + r, x * y) = 1
所以 gcd(a, (d_1 * d_2)) != 0就有答案
所以我们直接找到 a 的两个最小的因子(不同的两个)
只要两个因子都不 != 1即可
代码
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef double db;
const int N = 5e5 + 5, M = 1e7 + 5;
int prime[M], tot, shu[M];
int a[N], b[N], n, m;
void init() {
rep(i, 2, M) {
if (shu[i] == 0)
prime[++tot] = i;
rep(j, 1, tot) {
if ((ll)i * prime[j] > M) break;
shu[i * prime[j]] = prime[j];
if (i % prime[j] == 0) continue;
}
}
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
init();
cin >> n;
rep(i, 1, n) {
cin >> m;
if (shu[m] == 0) a[i] = b[i] = -1;
else {
int c = shu[m];
while (m % c == 0) m /= c;
if (m != 1) a[i] = c, b[i] = m;
else a[i] = b[i] = -1;
}
}
rep(i, 1, n) cout << a[i] << ' ';
cout << endl;
rep(i, 1, n) cout << b[i] << ' ';
return 0;
}