Problem p03454 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int mod = 1e9 + 7;

int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
pii exgcd(int a, int b) {
  if (b == 0)
    return pii(1, 0);

  pii t = exgcd(b, a % b);
  return pii(t.second, t.first - a / b * t.second);
}

int exp(int x, int n) {
  int ret = 1;
  while (n) {
    if (n & 1)
      ret = 1LL * ret * x % mod;
    x = 1LL * x * x % mod;
    n >>= 1;
  }
  return ret;
}

int solve(int a, int b, int c, ll limx, ll limy) {
  int d = gcd(a, b);
  if (c % d)
    return 0;

  a /= d;
  b /= d;
  c /= d;

  pii t = exgcd(a, b);
  ll Ra = t.first;
  ll Rb = t.second;

  Ra *= c;
  Rb *= c;

  Rb += Ra / b * a;
  Ra -= Ra / b * b;
  while (Ra <= 0) {
    Ra += b;
    Rb -= a;
  }
  if (Ra > limx)
    return 0;
  if (Rb <= 0)
    return 0;
  ll as = 0, ae = (1LL * limx - Ra) / b;
  ll bs = Rb <= limy ? 0 : (Rb - limy + a - 1) / a, be = (Rb - 1) / a;
  return max(0LL, min(ae, be) - max(as, bs) + 1) % mod;
}

int po[10];
int S;
int ans = 0;

int main() {
  po[0] = 1;
  for (int i = 1; i <= 9; i++) {
    po[i] = po[i - 1] * 10;
  }

  cin >> S;

  for (int a = 1; a <= 9; a++) {
    for (int b = a + 2; b <= 9; b++) {

      int cnt = 0;
      for (int i = a + 1; i < b; i++) {
        cnt += (po[i] - po[i - 1]) * i;
      }
      if (cnt >= S)
        continue;

      ans += solve(a, b, S - cnt, po[a] - po[a - 1], po[b] - po[b - 1]);
      ans %= mod;
    }
  }

  for (int i = 1; i <= sqrt(S); i++) {
    if (S % i == 0) {
      int tmp = exp(10, i) + mod - exp(10, i - 1);
      tmp %= mod;

      if (i > 9 || tmp >= S / i) {
        tmp += mod - S / i + 1;
        tmp %= mod;

        ans += tmp;
        ans %= mod;
      }

      if (i * i != S) {
        tmp = exp(10, S / i) + mod - exp(10, S / i - 1);
        tmp %= mod;

        if (S / i > 9 || tmp >= i) {
          tmp += mod - i + 1;
          tmp %= mod;

          ans += tmp;
          ans %= mod;
        }
      }
    }
  }

  for (int a = 1; a < 9; a++) {
    ans += solve(a, a + 1, S, po[a] - po[a - 1], po[a + 1] - po[a]);
    ans %= mod;
  }
  for (int a = 9; a <= S / 2; a++) {
    ans += solve(a, a + 1, S, 1e18, 1e18);
    ans %= mod;
  }

  cout << ans;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int mod = 1e9 + 7;

int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
pii exgcd(int a, int b) {
  if (b == 0)
    return pii(1, 0);

  pii t = exgcd(b, a % b);
  return pii(t.second, t.first - a / b * t.second);
}

int exp(int x, int n) {
  int ret = 1;
  while (n) {
    if (n & 1)
      ret = 1LL * ret * x % mod;
    x = 1LL * x * x % mod;
    n >>= 1;
  }
  return ret;
}

int solve(int a, int b, int c, ll limx, ll limy) {
  int d = gcd(a, b);
  if (c % d)
    return 0;

  a /= d;
  b /= d;
  c /= d;

  pii t = exgcd(a, b);
  ll Ra = t.first;
  ll Rb = t.second;

  Ra *= c;
  Rb *= c;

  Rb += Ra / b * a;
  Ra -= Ra / b * b;
  while (Ra <= 0) {
    Ra += b;
    Rb -= a;
  }
  if (Ra > limx)
    return 0;
  if (Rb <= 0)
    return 0;
  ll as = 0, ae = (1LL * limx - Ra) / b;
  ll bs = Rb <= limy ? 0 : (Rb - limy + a - 1) / a, be = (Rb - 1) / a;
  return max(0LL, min(ae, be) - max(as, bs) + 1) % mod;
}

int po[10];
int S;
int ans = 0;

int main() {
  po[0] = 1;
  for (int i = 1; i <= 9; i++) {
    po[i] = po[i - 1] * 10;
  }

  cin >> S;

  for (int a = 1; a <= 9; a++) {
    for (int b = a + 2; b <= 9; b++) {

      int cnt = 0;
      for (int i = a + 1; i < b; i++) {
        cnt += (po[i] - po[i - 1]) * i;
      }
      if (cnt >= S)
        continue;

      ans += solve(a, b, S - cnt, po[a] - po[a - 1], po[b] - po[b - 1]);
      ans %= mod;
    }
  }

  for (int i = 1; i <= sqrt(S); i++) {
    if (S % i == 0) {
      int tmp = exp(10, i) + mod - exp(10, i - 1);
      tmp %= mod;

      if (i > 9 || tmp >= S / i) {
        tmp += mod - S / i + 1;
        tmp %= mod;

        ans += tmp;
        ans %= mod;
      }

      if (i * i != S) {
        tmp = exp(10, S / i) + mod - exp(10, S / i - 1);
        tmp %= mod;

        if (S / i > 9 || tmp >= i) {
          tmp += mod - i + 1;
          tmp %= mod;

          ans += tmp;
          ans %= mod;
        }
      }
    }
  }

  for (int a = 1; a < 9; a++) {
    ans += solve(a, a + 1, S, po[a] - po[a - 1], po[a + 1] - po[a]);
    ans %= mod;
  }

  //*
  if (S >= 1e6) {
    for (int i = 2; i <= 10; i++) {
      if (S % i) {
        ans += solve(S / i, S / i + 1, S, 1e18, 1e18);
        ans %= mod;
      }
    }
    for (int a = 9; a < S / 10; a++) {
      ans += solve(a, a + 1, S, 1e18, 1e18);
      ans %= mod;
    }
    cout << ans;
    return 0;
  }
  //*/

  for (int a = 9; a <= S / 2; a++) {
    ans += solve(a, a + 1, S, 1e18, 1e18);
    ans %= mod;
  }

  cout << ans;
}