Как избежать TLE?

74
28 мая 2021, 15:20

Найдите количество правильных несократимых дробей, не превосходящих X, знаменатель которых не превосходит N.
Ограничения: 2 <= N <= 100000. X - макс. 4 знака после запятой.

В моей книге описано такое решение: строить ряд Фарея до тех пор, пока очередная дробь не будет больше чем X. Но при предельных значениях N, ответ может быть больше 10^9 (в последнем тесте ответ 3 * 10^9), а это значит, что с таким решением я словлю TLE. Написав реализацию, получил TLE.

Вот код:

#include <bits/stdc++.h>
using namespace std;
long double gcd(long double af, long double bf) {
    long a = af, b = bf;
    if (a < b) {
        swap(a, b);
    }
    while (b) {
        (a) %= b;
        swap(a, b);
    }
    return a;
}
long double lcm(long double a, long double b) 
{
    return a / gcd(a, b) * b;
}
long power[] = { 1, 10, 100, 1000, 10000, 100000, 1000000};
class fraction
{
    public:
        long double nominator;
        long double denominator;
        fraction(long nom, long denom): nominator(nom), denominator(denom)
        {}
        fraction(long double k)
        {
            k *= 10000;
            nominator = k / gcd(k, 10000);
            denominator = 10000 / gcd(k, 10000);
        }
        bool operator<=(fraction f)
        {
            long LCM = lcm(denominator, f.denominator);
            return (nominator * LCM / denominator <= f.nominator * LCM / f.denominator)? true : false;
        }
        void display()
        {
            cout << nominator << "/" << denominator << endl;
        }
};
int main()
{
    long double k;
    long N;
    long long count = 1;
    cin >> k;
    fraction K(k);
    cin >> N;
    fraction second(1, N-1);
    fraction first(1, N);
    while(second <= K)
    {
        count++;
        long long n = N, a = first.nominator, b = first.denominator, c = second.nominator, d = second.denominator;
        fraction temp(((n + b) / d)*c-a, ((n+b) / d)*d-b);
        first = second;
        second = temp;
    }
    cout << count;
}

Автор книги ошибся или моя реализация косячная?

READ ALSO
Как реализовать чтение и запись информации в классе разными способами?

Как реализовать чтение и запись информации в классе разными способами?

В Delphi для чтения и записи свойств можно использовать разные функцииЭто для примера

124
Убрать checked с потомков input[type=checkbox]

Убрать checked с потомков input[type=checkbox]

Как сделать так, чтоб при выборе страны снималось выделение со всех соответствующих городов и наоборот, при выборе города снималось выделение...

348
Как сверстать круговую диаграмму с фоновым изображением?

Как сверстать круговую диаграмму с фоновым изображением?

Внимание! Это дубль вопроса с тостера! Автор не я, просто вопрос показался интересным:

91