Problem p04016 (C++)

Buggy submission (status: Time Limit Exceeded):
#pragma once
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define bit(x, v) ((ll)x << v)

const ll INF = 1000000007;
const int MAX = 210000;
const int MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
int pr[100010];
void uini(int n) {
  for (size_t i = 0; i <= n; i++) {
    pr[i] = i;
  }
}

int parent(int x) {
  if (x == pr[x])
    return x;
  return pr[x] = parent(pr[x]);
}

bool unit(int x, int y) {
  int px = parent(x);
  int py = parent(y);

  if (px == py)
    return false;
  if (px < py) {
    pr[py] = px;
  } else {
    pr[px] = py;
  }
  return true;
}

// res[i][c] := i 文字目以降で最初に文字 c が登場する index (存在しないときは n)
vector<vector<int>> calcNext(const string &S) {
  int n = (int)S.size();
  vector<vector<int>> res(n + 1, vector<int>(26, n));
  for (int i = n - 1; i >= 0; --i) {
    for (int j = 0; j < 26; ++j)
      res[i][j] = res[i + 1][j];
    res[i][S[i] - 'a'] = i;
  }
  return res;
}
// mod 1000000007 の世界で a += b する関数
void add(long long &a, long long b) {
  a += b;
  if (a >= MOD)
    a -= MOD;
}
vector<int> ed[100010];
string s;
bool memo[100010];
bool check(int x, char col, int deep) {

  bool res = true;

  for (auto v : ed[x]) {

    if (s[v - 1] != col) {
      res = false;
      break;
    }
  }
  return res;
}
ll f(ll b, ll n) {
  if (b <= 1)
    return -1;
  if (b > n)
    return n;
  return f(b, n / b) + (n % b);
}

void solv() {
  ll n, s;
  cin >> n;
  cin >> s;
  if (n == s) {
    cout << n + 1 << endl;
    return;
  }
  ll pp = sqrt(n);
  ll bef = 0;
  for (ll i = 2; i <= 1000000; i++) {
    ll v = f(i, n);
    if (v == s) {
      cout << i << endl;
      return;
    }
    // if (bef < v)
    //	cout << i << " " << v << endl;
    // bef = v;
    // if (s == f(i, n)) {
    //	cout << i << endl;;
    // }
  }
  ll in = 1;
  ll ma = n;
  ll res = (s == 1) ? n : -1;
  while (ma >= pp) {
    ll tm = ma;
    in++;
    ma = (n / in) + 1;
    ll lo = ma;
    bool find = false;
    ll mid;
    ll count = 0;
    while (lo <= tm && count <= 50) {
      mid = (tm + lo) / 2LL;
      ll va = f(mid, n);
      if (va > s) {
        lo = mid;
      } else if (va < s) {
        tm = mid;
      } else {
        find = true;
        break;
      }
      count++;
    }
    if (find) {
      res = mid;
    }
  }
  if (res == -1) {
    cout << -1 << endl;
  } else
    cout << res << endl;
}

int main() {
  // COMinit();
  solv();

  return 0;
}


Fixed submission:
#pragma once
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define bit(x, v) ((ll)x << v)

const ll INF = 1000000007;
const int MAX = 210000;
const int MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
int pr[100010];
void uini(int n) {
  for (size_t i = 0; i <= n; i++) {
    pr[i] = i;
  }
}

int parent(int x) {
  if (x == pr[x])
    return x;
  return pr[x] = parent(pr[x]);
}

bool unit(int x, int y) {
  int px = parent(x);
  int py = parent(y);

  if (px == py)
    return false;
  if (px < py) {
    pr[py] = px;
  } else {
    pr[px] = py;
  }
  return true;
}

// res[i][c] := i 文字目以降で最初に文字 c が登場する index (存在しないときは n)
vector<vector<int>> calcNext(const string &S) {
  int n = (int)S.size();
  vector<vector<int>> res(n + 1, vector<int>(26, n));
  for (int i = n - 1; i >= 0; --i) {
    for (int j = 0; j < 26; ++j)
      res[i][j] = res[i + 1][j];
    res[i][S[i] - 'a'] = i;
  }
  return res;
}
// mod 1000000007 の世界で a += b する関数
void add(long long &a, long long b) {
  a += b;
  if (a >= MOD)
    a -= MOD;
}
vector<int> ed[100010];
string s;
bool memo[100010];
bool check(int x, char col, int deep) {

  bool res = true;

  for (auto v : ed[x]) {

    if (s[v - 1] != col) {
      res = false;
      break;
    }
  }
  return res;
}
ll f(ll b, ll n) {
  if (b <= 1)
    return -1;
  if (b > n)
    return n;
  return f(b, n / b) + (n % b);
}

void solv() {
  ll n, s;
  cin >> n;
  cin >> s;
  if (n == s) {
    cout << n + 1 << endl;
    return;
  }

  if (n == 1 && s > 1) {
    cout << -1 << endl;
    return;
  }
  ll pp = sqrt(n);
  ll bef = 0;
  for (ll i = 2; i <= 1000000; i++) {
    ll v = f(i, n);
    if (v == s) {
      cout << i << endl;
      return;
    }
    // if (bef < v)
    //	cout << i << " " << v << endl;
    // bef = v;
    // if (s == f(i, n)) {
    //	cout << i << endl;;
    // }
  }
  ll in = 1;
  ll ma = n;
  ll res = (s == 1) ? n : -1;
  while (ma >= pp) {
    ll tm = ma;
    in++;
    ma = (n / in) + 1;
    ll lo = ma;
    bool find = false;
    ll mid;
    ll count = 0;
    while (lo <= tm && count <= 50) {
      mid = (tm + lo) / 2LL;
      ll va = f(mid, n);
      if (va > s) {
        lo = mid;
      } else if (va < s) {
        tm = mid;
      } else {
        find = true;
        break;
      }
      count++;
    }
    if (find) {
      res = mid;
    }
  }
  if (res == -1) {
    cout << -1 << endl;
  } else
    cout << res << endl;
}

int main() {
  // COMinit();
  solv();

  return 0;
}