CF1366D Two Divisors

原题链接

  • 题意:给出 \(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();
    }
}
posted @ 2021-05-10 21:22  u_yan  阅读(42)  评论(0编辑  收藏  举报