C/C++教程

cf1089 F. Fractions(数论)

本文主要是介绍cf1089 F. Fractions(数论),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题意:

给定正整数 n,构造不超过 1e5 个真分数,要求这些真分数的和为 \(1-\frac 1{n}\) ,且每个真分数的分母都是小于 n 的 n 的因数。

思路:

答案一定形如 $\frac {cx}{n} + \frac{dy}{n} + \cdots $,其中 \(x,y\) 是 \(n\) 的因子。因为这样才能让约分后的分子小于 \(n\) 。同时还要有 \(cx+dy+\cdots =n-1\) 。

因为 \(n-1\) 与 \(n\) 互质,由裴蜀定理知 \(x,y\) 互质。如果 \(n\) 只有一个质因子就没有答案。否则任取 \(n\) 的两个不同质因子。

下面证明只需要两个分数就能构造出答案:

\[cx + dy = n-1\implies c =\frac{n-(1+dy)}{x} \\ c\in \mathbb{N^+} ,x|n \implies x |(1+dy),1+dy<n \]

当 \(d\) 取遍 \(1\sim x-1\) 时,\(dy\) 都不是 \(x\) 的倍数,且易证 \(dy\) 两两不同。所以 \(dy\pmod x\) 以某种顺序取遍 \(1\sim x-1\) 。所以存在 \(d\in [1,x-1]\),\(dy\equiv x-1\pmod x\implies x|(1+dy)\)。

所以 \(1+dy \le 1+(x-1)y = xy+1-y<xy\le n\) 。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, p[N], idx;
signed main()
{
    scanf("%d", &n); int nn = n;
    
    for(int i = 2; i <= sqrt(n); i++) //分解质因子
    {
        if(n % i == 0) p[++idx] = i;
        while(n % i == 0) n /= i;
    }
    if(n > 1) p[++idx] = n;
    
    n = nn;
    if(idx < 2) return puts("NO"), 0;

    int x = p[1], y = p[2], c, d = 1;
    while((1+d*y) % x) d++; //找d
    c = (n-1-d*y)/x;
    
    printf("YES\n2\n%d %d\n%d %d", c, n/x, d, n/y);

    return 0;
}

这篇关于cf1089 F. Fractions(数论)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!