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

#include <bits/stdc++.h>
#define _GLIBCXX_DEBUG
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define Sort(a) sort(a.begin(), a.end())
#define Reve(a) reverse(a.begin(), a.end())
#define PI 3.14159265359
typedef long long ll;
const ll MOD = 1e9 + 7;

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
/*ll myPow(ll x, ll n, ll m){
  if(n == 0)
    return 1;
  if(n % 2 == 0)
    return myPow(x * x % m, n / 2, m);
  else
    return x * myPow(x, n - 1, m) % m;
}*/

ll lcm(ll a, ll b) {
  ll g = gcd(a, b);
  b /= g;
  a *= b;
  return a;
}

// 素数判定 O(√n)
bool is_prime(int64_t n) {
  for (int64_t i = 2; i * i <= n; i++) {
    if (n % i == 0)
      return false;
  }
  return n != 1;
}

// 約数の列挙 O(√n)
vector<int64_t> dividor(int64_t n) {
  vector<int64_t> res;
  for (int64_t i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      res.push_back(i);
      if (i != n / i)
        res.push_back(i);
    }
  }
  return res;
}

// 素因数分解 O(√n)
map<int64_t, int64_t> prime_factor(int64_t n) {
  map<int64_t, int64_t> res;
  for (int64_t i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      res[i]++;
      n /= i;
    }
  }
  if (n != 1)
    res[n] = 1;
  return res;
}
struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

  UnionFind(int N) : par(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

/*int main(){
  int n, m, q; cin >> n >> m >> q;
  vector<int> C(q), D(q), A(m, 1);
  //vector<pair<int, int>> AB(q);
  map<int, tuple<int, int, int>> S;

  vector<int> E(n, -1);*/
/*rep(i, q) cin >> AB[i].first >> AB[i].second >> C[i] >> D[i];*/
/*rep(i, q){
  int a, b, c, d;
  cin >> a >> b >> c >> D[i];
  S[d] = make_tuple(a, b, c);
}
Sort(D);
int ans=0;*/

/*rep(i, q){
  int da=D[i];
  int n1 = get<0>(S[da]);
  int n2 = get<1>(S[da]);
  int n3 = get<1>(S[da]);
  if(E[n1-1]==-1&&E[n2-1]==-1) {
    if(n1+n3<=m){
      E[n1-1]=n1;
      E[n2-1]=n1+n3;
    }
    if(n1+n3<)
  }
  else if(E[AB[i].first-1]==-1){

  }*/
//}
//}

int main() {
  // cout << 2 << endl;
  ll a, b, n;
  cin >> a >> b >> n;
  if (n <= 1000000000) {
    ll ans = 0;
    ll tmp = 0;
    rep(i, n + 1) {
      ll g = (a * i) / b;
      ll h = i / b;
      if (tmp < g - a * h) {
        tmp = g - a * h;
        ans = i;
      }
    }
    cout << tmp << endl;
  } else {
    // ll n1 = (ll) sqrt(n);
    // cout << n1 << endl;
    /*ll ans = 0; ll tmp = 0;
    for(ll i=n; i>n-b; i--){
      ll g = a*i/b;
      ll h = i/b;
      if(tmp<g-a*h) {tmp=g-a*h; ans = i;}
    }*/
    ll tmp1 = 0;
    if (n > b - 1) {
      ll g1 = a * (b - 1) / b;
      ll h1 = (b - 1) / b;
      tmp1 = g1 - a * h1;
    }
    ll g2 = a * n / b;
    ll h2 = n / b;
    ll tmp2 = g2 - a * h2;
    cout << max(tmp1, tmp2) << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define _GLIBCXX_DEBUG
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define Sort(a) sort(a.begin(), a.end())
#define Reve(a) reverse(a.begin(), a.end())
#define PI 3.14159265359
typedef long long ll;
const ll MOD = 1e9 + 7;

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}
/*ll myPow(ll x, ll n, ll m){
  if(n == 0)
    return 1;
  if(n % 2 == 0)
    return myPow(x * x % m, n / 2, m);
  else
    return x * myPow(x, n - 1, m) % m;
}*/

ll lcm(ll a, ll b) {
  ll g = gcd(a, b);
  b /= g;
  a *= b;
  return a;
}

// 素数判定 O(√n)
bool is_prime(int64_t n) {
  for (int64_t i = 2; i * i <= n; i++) {
    if (n % i == 0)
      return false;
  }
  return n != 1;
}

// 約数の列挙 O(√n)
vector<int64_t> dividor(int64_t n) {
  vector<int64_t> res;
  for (int64_t i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      res.push_back(i);
      if (i != n / i)
        res.push_back(i);
    }
  }
  return res;
}

// 素因数分解 O(√n)
map<int64_t, int64_t> prime_factor(int64_t n) {
  map<int64_t, int64_t> res;
  for (int64_t i = 2; i * i <= n; i++) {
    while (n % i == 0) {
      res[i]++;
      n /= i;
    }
  }
  if (n != 1)
    res[n] = 1;
  return res;
}
struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

  UnionFind(int N) : par(N) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};

/*int main(){
  int n, m, q; cin >> n >> m >> q;
  vector<int> C(q), D(q), A(m, 1);
  //vector<pair<int, int>> AB(q);
  map<int, tuple<int, int, int>> S;

  vector<int> E(n, -1);*/
/*rep(i, q) cin >> AB[i].first >> AB[i].second >> C[i] >> D[i];*/
/*rep(i, q){
  int a, b, c, d;
  cin >> a >> b >> c >> D[i];
  S[d] = make_tuple(a, b, c);
}
Sort(D);
int ans=0;*/

/*rep(i, q){
  int da=D[i];
  int n1 = get<0>(S[da]);
  int n2 = get<1>(S[da]);
  int n3 = get<1>(S[da]);
  if(E[n1-1]==-1&&E[n2-1]==-1) {
    if(n1+n3<=m){
      E[n1-1]=n1;
      E[n2-1]=n1+n3;
    }
    if(n1+n3<)
  }
  else if(E[AB[i].first-1]==-1){

  }*/
//}
//}

int main() {
  // cout << 2 << endl;
  ll a, b, n;
  cin >> a >> b >> n;
  if (n <= 1000000000) {
    ll ans = 0;
    ll tmp = 0;
    rep(i, n + 1) {
      ll g = (a * i) / b;
      ll h = i / b;
      if (tmp < g - a * h) {
        tmp = g - a * h;
        ans = i;
      }
    }
    cout << tmp << endl;
  } else {
    ll n1 = (ll)sqrt(n);
    // cout << n1 << endl;
    ll ans = 0;
    ll tmp = 0;
    for (ll i = n; i > n - b; i--) {
      ll g = a * i / b;
      ll h = i / b;
      if (tmp < g - a * h) {
        tmp = g - a * h;
        ans = i;
      }
    }
    /*ll g1 = a*(b-1)/b;
    ll h1 = (b-1)/b;
    tmp = max(tmp, g1-a*h1);*/
    cout << tmp << endl;
  }
}