原题链接
- 题意:给出 (n) 个数,然后求出每个数是否存在两个因子大于 (1) 并且 (gcd(d_1+d_2, a_i) = 1)。
- 题解:可以知道,如果 (gcd(x,y)=1) 那么必然有 (forall p in (y equiv 0 mod p)) 并且 (x equiv 0mod p) 。存在质因子,把质因数分解成两部分,这样这两部分模另一部分的任何素数都不为 (0) 所以这两部分模对面部分的质数都不是 (0),那么这两部分相加,所有 (a_i) 的质因数都取模不为 (0),所以就是和 (a_i) 互质。
- 代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll
;
const int N = 1e7+9;
int pr[N];
int mark[N];
int a[N];
int ans1[N], ans2[N];
int pr_cnt = 0;
void getpr() {
for (int i = 2; i < N; i ++) {
if (!mark[i])
pr[++pr_cnt] = i;
for (int j = 1; j <= pr_cnt &&(ll)pr[j] * i < N; j ++) {
mark[pr[j] * i] = pr[j];
if (i % pr[j] == 0) {
break;
}
}
}
}
void solve() {
int n;scanf("%d", &n);
for (int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
if (mark[a[i]]&&mark[a[i]] != a[i]) {
ans1[i] = mark[a[i]];
ll d = a[i];
while (d % ans1[i] == 0)d /= ans1[i];
ans2[i]= d;
if (d == 1)ans1[i] = ans2[i] = 0;
}
}
for (int i = 1; i <= n; i ++) {
if (ans1[i] == 0)ans1[i] = -1;
if (ans2[i] == 0)ans2[i] = -1;
printf("%d ", ans1[i]);
}puts("");
for (int j = 1; j <= n; j ++) {
printf("%d ", ans2[j]);
}
puts("");
}
int main() {
ios::sync_with_stdio(0);
int t=1;//cin >> t;
getpr();
while (t--) {
solve();
}
}