原题链接
- 题意:给出 \(n\) 个数,然后求出每个数是否存在两个因子大于 \(1\) 并且 \(gcd(d_1+d_2, a_i) = 1\)。
- 题解:可以知道,如果 \(gcd(x,y)=1\) 那么必然有 \(\forall p \in (y \equiv 0 \mod p)\) 并且 \(x \equiv 0\mod 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();
}
}