P9796 Fractions

· · 题解

题目大意

给定一个正整数 n,构造出若干个形如 \frac{a_i} {b_i} 的真分数,使得 \sum_{i=1} ^{k} \frac{a_i} {b_i} =1-\frac {1} {n},且 b_in 的因数。

题目分析

由于 b_in 的因数,所以我们直觉上先把 n 分解一下:

n = p_1^{c_1} p_2^{c_2}\cdots p_m^{c_m}

代码实现

经过以上分析,代码就可以写出来了。我们先把 n 分解质因数,然后选取 xy,使 \gcd(x,y)=1,x\cdot y = n。然后从 1x-1 枚举 a,每次进行一个判断即可。时间复杂度 O(\sqrt{n})

最后贴上代码,码风很丑轻点喷。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 100005
inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}

int vis[maxn], prime[maxn], n, m;

void init() {
    for (int i = 2; i <= 100000; i++) {
        if (!vis[i]) prime[++m] = i, vis[i] = 1;
        for (int j = 1; j <= m && prime[j] * i <= 100000; j++) 
            vis[prime[j] * i] = 1;
    }
}

struct node {
    int v, cnt;
};

vector<node> a;

int ksm(int a, int b) {
    int res = 1;
    for (; b; b >>= 1) {
        if (b & 1) res = res * a;
        a = a * a;
    }
    return res;
}

signed main() {
    init();
    n = read();
    for (int i = 1; i <= m; i++) {
        if (n % prime[i] == 0) {
            int tmp = n, cnt = 0;
            while (tmp % prime[i] == 0) {
                cnt++;
                tmp /= prime[i];
            }
            node nw; nw.cnt = cnt, nw.v = prime[i];
            a.push_back(nw);
            break;
        }
    }
    if (a.empty() || ksm(a[0].v, a[0].cnt) == n) {
        puts("NO");
        return 0;
    }
    puts("YES");
    int x = ksm(a[0].v, a[0].cnt);
    int y = n / x, a, b;
    for (a = 1; a < x; a++) {
        if ((n - 1 - a * y) % x == 0) {
            b = (n - 1 - a * y) / x;
            break;
        }
    }
    cout << 2 << endl;
    cout << a << " " << x << endl << b << " " << y;
}