AT3518 4/N
既然是埃及分数,考虑用这题的方法来解,可以去看对这题的题解。
但是这两题还是有点不同的,我们可以考虑这题有一些题解,因为并没有要求分解出的 不相同,所以我们考虑当 是偶数时,,而用搜索其实会耗时很久。
代码改一下即可:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <utility>
#include <cmath>
#include <cstring>
using namespace std;
#define int unsigned long long
static char buf[1000000], * p1 = buf, * p2 = buf;
#define getchar() p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++
inline int read()
{
register char ch = getchar();
register int x = 0;
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x;
}
inline void write(int x)
{
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
inline int gcd(register int a, register int b) // 计算最大公因数
{
return (b == 0 ? a : gcd(b, a % b));
}
#define lcm(a, b) (a * b / gcd(a, b)) // 最小公倍数
inline pair<int, int> add(const pair<int, int>& a, const pair<int, int>& b) // a.first 表示第一个分数的分子,a.second 表示第一个分数的分母,b.first 表示第二个分数的分子,b.second 表示第二个分数的分母
{
register int newfm = lcm(a.second, b.second);
register int newfz = newfm / a.second * a.first + newfm / b.second * b.first;
register int g = gcd(newfm, newfz);
newfm /= g;
newfz /= g;
return make_pair(newfz, newfm);
}
inline pair<int, int> Minus(register const pair<int, int>& a, register const pair<int, int>& b)
{
register int newfm = lcm(a.second, b.second);
register int newfz = newfm / a.second * a.first - newfm / b.second * b.first;
register int g = gcd(newfm, newfz);
newfm /= g;
newfz /= g;
return make_pair(newfz, newfm);
}
inline bool bigger(register const pair<int, int>& a, register const pair<int, int>& b) // 返回第一个分数 >= 第二个分数
{
register int newfm = lcm(a.second, b.second);
register int nfz1 = newfm / a.second * a.first;
register int nfz2 = newfm / b.second * b.first;
return nfz1 >= nfz2;
}
inline bool big(register const pair<int, int>& a, register const pair<int, int>& b) // 返回第一个分数 >= 第二个分数
{
register int newfm = lcm(a.second, b.second);
register int nfz1 = newfm / a.second * a.first;
register int nfz2 = newfm / b.second * b.first;
return nfz1 > nfz2;
}
const int N = 1e5 + 5;
int a, b, tdep;
pair<int, int> k;
int arr[N], res[N];
inline void dfs(register int dep, register pair<int, int> p)
{
if (dep == tdep)
{
register pair<int, int> q = Minus(k, p);
if (q.first != 1) return;
arr[dep] = q.second;
for (register int i = 1; i <= tdep; ++i) printf("%llu ", arr[i]);
puts("");
exit(0);
return;
}
register pair<int, int> t = Minus(make_pair(a, b), make_pair(p.first, p.second));
register int minn = max((int)arr[dep - 1], (int)ceil(t.second * 1.0 / t.first));
register int l = tdep - dep + 1;
for (register int i = minn; big(add(p, make_pair(l, i)), k); ++i)
{
arr[dep] = i;
dfs(dep + 1, add(p, make_pair(1, i)));
}
}
signed main()
{
a = 4, b = read();
k.first = a;
k.second = b;
if (b == 2)
{
printf("1 2 2\n");
return 0;
}
else if (b % 2 == 0)
{
printf("%llu %llu %llu\n", b, b, b >> 1llu);
return 0;
}
register int tmp = gcd(a, b);
a /= tmp;
b /= tmp;
register int i, j;
memset(res, 0, sizeof(res));
tdep = 3;
dfs(1, make_pair(0, 1));
return 0;
}

浙公网安备 33010602011771号