[codeforces 1366D] Two Divisors

题意

(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;
}
原文地址:https://www.cnblogs.com/2aptx4869/p/13158087.html