cf 1366D Two Divisors - 数论 gcd性质

传送门
找到\(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], " \n"[i == n]);
    for(int i = 1; i <= n; i++)
        printf("%d%c", y[i], " \n"[i == n]);
}
posted @ 2020-12-25 17:22  Emcikem  阅读(123)  评论(0编辑  收藏  举报