Problem p03454 (C++)

Buggy submission (status: Time Limit Exceeded):

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

typedef long long ll;

int S;
ll ans = 0;
ll mod = 1000000007;
ll F[100010];

int f(int i) {
  int res = 0;
  while (i)
    i /= 10, res++;
  return res;
}

ll pow_mod(ll a, ll b) {
  if (b == 0)
    return 1;
  ll res = pow_mod(a * a % mod, b / 2);
  if (b & 1)
    res = res * a % mod;
  return res;
}

int main() {
  scanf("%d", &S);

  int l = 1, r = 1, sum = 0, ll = 10, rr = 10, nl = 1, nr = 1;
  while (1) {
    while (r != 100000000 && sum < S) {
      sum += nr;
      r++;
      if (r == rr) {
        rr *= 10;
        nr++;
      }
    }
    while (sum > S) {
      sum -= nl;
      l++;
      if (l == ll) {
        ll *= 10;
        nl++;
      }
    }
    if (r == 100000000)
      break;
    if (sum == S && f(l) != f(r - 1))
      ans++;
    sum -= nl;
    l++;
    if (l == ll) {
      ll *= 10;
      nl++;
    }
  }

  for (int i = 1; i <= (int)sqrt((double)S); i++) {
    if (S % i == 0) {
      if (i * i == S) {
        if (i >= 9 || pow_mod(10, i - 1) * 9 + 1 >= i) {
          ans += (mod + pow_mod(10, i - 1) * 9 - i + 1) % mod;
        }
      } else {
        if (i >= 9 || pow_mod(10, i - 1) * 9 + 1 >= S / i) {
          ans += (mod + pow_mod(10, i - 1) * 9 - S / i + 1) % mod;
        }
        if (S / i >= 9 || pow_mod(10, S / i - 1) * 9 + 1 >= i) {
          ans += (mod + pow_mod(10, S / i - 1) * 9 - i + 1) % mod;
        }
      }
    }
  }

  ans += S / 8 - (S % 8 == 0);
  ans %= mod;

  for (int i = 1; i <= (int)sqrt((double)(S)); i++) {
    if (S % i == 0 && i < S / 8) {
      if (i * i == S)
        ans--;
      else {
        ans--;
        if (S / i < S / 8)
          ans--;
      }
      ans %= mod;
    }
  }

  printf("%lld\n", ans);
  return 0;
}


Fixed submission:

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

typedef long long ll;

int S;
ll ans = 0;
ll mod = 1000000007;
ll F[100010];

int f(int i) {
  int res = 0;
  while (i)
    i /= 10, res++;
  return res;
}

ll pow_mod(ll a, ll b) {
  if (b == 0)
    return 1;
  ll res = pow_mod(a * a % mod, b / 2);
  if (b & 1)
    res = res * a % mod;
  return res;
}

int main() {
  scanf("%d", &S);

  int l = 1, r = 1, sum = 0, ll = 10, rr = 10, nl = 1, nr = 1;
  while (1) {
    while (r != 100000000 && sum < S) {
      sum += nr;
      r++;
      if (r == rr) {
        rr *= 10;
        nr++;
      }
    }
    while (sum > S) {
      sum -= nl;
      l++;
      if (l == ll) {
        ll *= 10;
        nl++;
      }
    }
    if (r == 100000000)
      break;
    if (sum == S && nl != nr - (r == rr / 10))
      ans++;
    sum -= nl;
    l++;
    if (l == ll) {
      ll *= 10;
      nl++;
    }
  }

  for (int i = 1; i <= (int)sqrt((double)S); i++) {
    if (S % i == 0) {
      if (i * i == S) {
        if (i >= 9 || pow_mod(10, i - 1) * 9 + 1 >= i) {
          ans += (mod + pow_mod(10, i - 1) * 9 - i + 1) % mod;
        }
      } else {
        if (i >= 9 || pow_mod(10, i - 1) * 9 + 1 >= S / i) {
          ans += (mod + pow_mod(10, i - 1) * 9 - S / i + 1) % mod;
        }
        if (S / i >= 9 || pow_mod(10, S / i - 1) * 9 + 1 >= i) {
          ans += (mod + pow_mod(10, S / i - 1) * 9 - i + 1) % mod;
        }
      }
    }
  }

  ans += S / 8 - (S % 8 == 0);
  ans %= mod;

  for (int i = 1; i <= (int)sqrt((double)(S)); i++) {
    if (S % i == 0 && i < S / 8) {
      if (i * i == S)
        ans--;
      else {
        ans--;
        if (S / i < S / 8)
          ans--;
      }
      ans %= mod;
    }
  }

  printf("%lld\n", ans);
  return 0;
}