Problem p00811 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define all(c) c.begin(), c.end()
#define rall(c) c.rbegin(), c.rend()
#define mp(a, b) make_pair((a), (b))
#define eq ==

typedef long long ll;
typedef complex<double> point;
typedef pair<int, int> pii;

// →↑←↓
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

const double EPS = 1e-9;

void sieve(vector<int> &primes) {
  const int M = 100010;
  bool isPrime[M];
  for (int i = 2; i < M; i++)
    isPrime[i] = true;
  for (int i = 2; i * i < M; i++) {
    if (not isPrime[i])
      continue;
    for (int j = i * i; j < M; j += i) {
      isPrime[j] = false;
    }
  }
  for (int i = 2; i < M; i++) {
    if (isPrime[i])
      primes.push_back(i);
  }
}

int main() {
  vector<int> primes;
  sieve(primes);
  while (true) {
    ll m, a, b;
    cin >> m >> a >> b;
    if (m == 0)
      break;
    ll maxpq = -1;
    ll retp, retq;
    for (int i = 0; i < primes.size(); i++) {
      int lower = 0, upper = primes.size() - 1;
      for (int j = 0; j < 100; j++) {
        int mid = (lower + upper) / 2;
        ll p = primes[i], q = primes[mid];
        if (p * q <= m and a * q <= p * b) {
          lower = mid;
        } else {
          upper = mid;
        }
      }
      ll p = primes[i], q = primes[lower];
      if (p <= q and p * q >= maxpq) {
        maxpq = p * q;
        retp = p, retq = q;
      }
    }
    cout << retp << " " << retq << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define all(c) c.begin(), c.end()
#define rall(c) c.rbegin(), c.rend()
#define mp(a, b) make_pair((a), (b))
#define eq ==

typedef long long ll;
typedef complex<double> point;
typedef pair<int, int> pii;

// →↑←↓
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

const double EPS = 1e-9;

void sieve(vector<int> &primes) {
  const int M = 50005;
  bool isPrime[M];
  for (int i = 2; i < M; i++)
    isPrime[i] = true;
  for (int i = 2; i * i < M; i++) {
    if (not isPrime[i])
      continue;
    for (int j = i * i; j < M; j += i) {
      isPrime[j] = false;
    }
  }
  for (int i = 2; i < M; i++) {
    if (isPrime[i])
      primes.push_back(i);
  }
}

int main() {
  vector<int> primes;
  sieve(primes);
  while (true) {
    ll m, a, b;
    cin >> m >> a >> b;
    if (m == 0)
      break;
    ll maxcd = -1;
    ll retc, retd;
    for (int i = 0; i < primes.size(); i++) {
      for (int j = i; j < primes.size(); j++) {
        ll c = primes[i];
        ll d = primes[j];
        ll cd = c * d;
        if (cd <= m and a * d <= c * b and maxcd < cd) {
          maxcd = cd;
          retc = c, retd = d;
        }
      }
    }
    cout << retc << " " << retd << endl;
  }
  return 0;
}