Codeforces传送门
You are given a positive integer n n n.
Find a sequence of fractions
a
i
b
i
,
i
=
1
…
k
\frac{a_i}{b_i}, i=1…k
biai,i=1…k(where
a
i
a_i
ai and
b
i
b_i
bi are positive integers) for some
k
k
k such that:
{
b
i
divides
n
,
1
<
b
i
<
n
for
i
=
1
…
k
1
≤
a
i
<
b
i
for
i
=
1
…
k
∑
i
=
1
k
a
i
b
i
=
1
−
1
n
\begin{cases} \text{$b_i$ divides $n$, $1 < b_i < n$ for $i = 1 \ldots k$} \\ \text{$1 \le a_i < b_i$ for $i = 1 \ldots k$} \\ \text{$\sum\limits_{i=1}^k \frac{a_i}{b_i} = 1 - \frac{1}{n}$} \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧bi divides n, 1<bi<n for i=1…k1≤ai<bi for i=1…ki=1∑kbiai=1−n1
Input
The input consists of a single integer n n n ( 2 ≤ n ≤ 1 0 9 2≤n≤10^9 2≤n≤109).
Output
In the first line print “YES” if there exists such a sequence of fractions or “NO” otherwise.
If there exists such a sequence, next lines should contain a description of the sequence in the following format.
The second line should contain integer k k k ( 1 ≤ k ≤ 100000 1≤k≤100000 1≤k≤100000) — the number of elements in the sequence. It is guaranteed that if such a sequence exists, then there exists a sequence of length at most 100000 100000 100000.
Next k k k lines should contain fractions of the sequence with two integers a i a_i ai and b i b_i bi on each line.
Examples
input
2
output
NO
input
6
output
YES
2
1 2
1 3
Note
In the second example there is a sequence 1 2 , 1 3 \frac{1}{2},\frac{1}{3} 21,31 such that 1 2 + 1 3 = 1 − 1 6 \frac{1}{2}+ \frac{1}{3}=1−\frac{1}{6} 21+31=1−61.
解题分析
首先我们把要求的式子乘 n n n, 那么就变成了这个问题: 求 p 1 k 1 + p 2 k 2 + . . . + p m k m = n − 1 p_1k_1+p_2k_2+...+p_mk_m=n-1 p1k1+p2k2+...+pmkm=n−1的一组非负整数解, 其中 p i p_i pi是 n n n不同的质因子。
那么我们回想起NOIP2017Day1T1可以想到有一个叫裴蜀定理的东西, 有这样一个结论: 两个数不能凑出来的最大整数是
a
×
b
−
a
−
b
a\times b-a-b
a×b−a−b。 所以似乎只要有两个不同质数就一定可以凑出来了, 用
e
x
g
c
d
exgcd
exgcd解一组解即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define R register
#define MX 100500
#define IN inline
int k, pcnt, tot;
int pri[MX], p[20];
bool vis[MX];
int exgcd(int a, int b, int &x, int &y)
{
if(!b) return x = 1, y = 0, a;
int ret = exgcd(b, a % b, x, y);
int buf = x; x = y, y = buf - a / b * y;
return ret;
}
IN void get()
{
int bd = std::sqrt(k), tar = k;
for (R int i = 2; i <= bd; ++i)
{
if (!vis[i])
{
pri[++pcnt] = i;
if (!(tar % i)){
tar /= i, p[++tot] = i;
while(!(tar % i)) tar /= i;
}
}
for (R int j = 1; j <= pcnt; ++j)
{
if (pri[j] * i > bd) break;
vis[pri[j] * i] = true;
if (!(i % pri[j])) break;
}
}
if (tar != 1 && tar > bd) p[++tot] = tar;
}
void solve()
{
int x, y;
if (tot == 1) return puts("NO"), void();
puts("YES");
int gcd = exgcd(p[1], p[2], x, y);
int fac1 = k / p[1], fac2 = k / p[2];
if (x < 0) printf("2\n%d %d\n%d %d", -x, fac1, fac2 - y, fac2);
else printf("2\n%d %d\n%d %d", fac1 - x, fac1, -y, fac2);
}
int main(void)
{
scanf("%d", &k);
get();
solve();
}