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

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

int memo[12001][8];
int b_pow(int a, int b) {
  if (memo[a][b])
    return memo[a][b];
  else if (b == 0)
    return 1;
  else if (b == 1)
    return a;
  else
    return memo[a][b] = b_pow(a, b / 2) * b_pow(a, (b + 1) / 2);
}
int ans, A;

int dfs(int p, int q, int k, int product, int current) {
  // productがoverflowした。(produt <= 0)　
  if (product <= 0 || product > A || p * current > k * q)
    return 0;
  if (p == 0)
    return 1;
  if (current * product > A || k == 0 || p == 0)
    return 0;

  int ans = 0;
  // {1/current}を何回使うかを決める
  for (int i = 0; i <= k; i++) {
    if (p * current >= i * q) {
      int bunsi = p * current - i * q;
      int bunbo = q * current;
      if (bunsi != 0) {
        int g = __gcd(bunsi, bunbo);
        bunsi /= g, bunbo /= g;
      }
      ans += dfs(bunsi, bunbo, k - i, product * b_pow(current, i), current + 1);
    } else {
      break;
    }
  }
  return ans;
}

int main() {
  int a, b, c, d;
  while (cin >> a >> b >> c >> d, a || b || c || d) {
    A = c;
    cout << dfs(a, b, d, 1, 1) << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define INF 100000000

typedef long long ll;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};

int P, Q;
int A, N;
int ans;

struct fraction {
  ll mother;
  ll child;
  fraction(ll x, ll y) : mother(x), child(y) {}
  fraction &operator+=(const fraction &p) {
    child = mother * p.child + p.mother * child;
    mother = mother * p.mother;
    reduction();
    return *this;
  }
  fraction &operator-=(const fraction &p) {
    child = p.mother * child - mother * p.child;
    mother = mother * p.mother;
    reduction();
    return *this;
  }
  fraction operator-(const fraction &p) const {
    fraction ret(mother, child);
    ret -= p;
    return ret;
  }
  fraction operator+(const fraction &p) const {
    fraction ret(mother, child);
    ret += p;
    return ret;
  }
  fraction operator*(const ll p) {
    fraction ret(mother, child);
    ret.child *= p;
    ret.reduction();
    return ret;
  }
  bool operator>(const fraction p) const {
    return child * p.mother > p.child * mother;
  }
  void reduction(void) {
    ll ma = max(mother, child);
    for (ll i = 2; i * i <= ma; i++) {
      if (mother % i == 0 && child % i == 0) {
        while (mother % i == 0 && child % i == 0) {
          mother /= i;
          child /= i;
        }
      }
    }
  }
};

void dfs_log(fraction bunsu, ll seki, ll nokori, ll now,
             vector<fraction> log = vector<fraction>()) {
  if (bunsu.child == 1 && seki * bunsu.mother <= A && bunsu.mother >= now) {
    ans++;
    for (ll i = 0; i < log.size(); i++) {
      fraction f = log[i];
      std::cout << f.child << '/' << f.mother << ' ';
    }
    std::cout << "1/" << bunsu.mother << std::endl;
    std::cout << std::endl;
  }
  if (nokori == 0)
    return;
  for (ll i = now; i * seki <= A; i++) {
    fraction tmp = bunsu - fraction(i, 1);
    if (tmp.child > 0) {
      vector<fraction> log_temp = log;
      log_temp.push_back(fraction(i, 1));
      dfs_log(tmp, seki * i, nokori - 1, i, log_temp);
    }
  }
}

int dfs(fraction &bunsu, ll seki, ll nokori, ll now) {
  int ret = 0;
  if (bunsu.child == 1 && seki * bunsu.mother <= A && bunsu.mother >= now)
    ret++;
  if (nokori == 0)
    return ret;
  for (ll i = now; i * seki <= A; i++) {
    if (bunsu > fraction(i, 1) * (nokori + 1))
      break;
    fraction tmp = bunsu - fraction(i, 1);
    if (tmp.child > 0)
      ret += dfs(tmp, seki * i, nokori - 1, i);
  }
  return ret;
}

int main(void) {
  while (cin >> P >> Q >> A >> N) {
    if (P == 0 && Q == 0 && A == 0 && N == 0)
      break;
    fraction bunsu(Q, P);
    bunsu.reduction();
    ans = 0;
    cout << dfs(bunsu, 1, N - 1, 1) << endl;
  }
  return 0;
}