Problem p03454 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919LL
#define MOD 1000000007
#define int long long

int modpow(int x, int k) {
  int a = 1;
  while (k > 0) {
    if (k & 1)
      a = (1LL * a * x) % MOD;
    x = (1LL * x * x) % MOD;
    k >>= 1;
  }
  return a;
}
int gcd(int a, int b) {
  if (a > b)
    swap(a, b);
  if (a == 0)
    return b;
  return gcd(b % a, a);
}
int xGCD(int a, int b, int &x, int &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  int x1, y1, gcd = xGCD(b, a % b, x1, y1);
  x = y1;
  y = x1 - (a / b) * y1;
  return gcd;
}

int S;
int num[11];
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  num[1] = 9;
  for (int i = 2; i <= 10; i++)
    num[i] = 10LL * num[i - 1];

  cin >> S;
  vector<int> ds;
  for (int d = 1; d * d <= S; d++)
    if (S % d == 0)
      ds.pb(d), ds.pb(S / d);
  sort(all(ds));
  uniq(ds);
  int s = 0;
  for (int f : ds) {
    int n = S / f;
    if (f <= 9 && n > num[f])
      continue;
    s = (s + 9LL * modpow(10, f - 1) + 1 + MOD - n) % MOD;
  }
  for (int a = 10; a <= S; a++) {
    int x0 = -S, y0 = S;
    int lo = (1 - x0 + a) / (a + 1);
    int hi = (y0 - 1) / a;
    if (lo <= hi)
      s = (s + hi - lo + 1) % MOD;
  }

  for (int a = 1; a <= 10; a++) {
    for (int b = a + 1; b <= 10; b++) {
      int g = gcd(a, b);
      long long c = S;
      for (int x = a + 1; x <= b - 1; x++)
        c -= 1LL * x * num[x];
      if (c <= 0 || c % g)
        continue;
      int x0, y0;
      xGCD(a, b, x0, y0);
      x0 *= c / g;
      y0 *= c / g;
      assert(a * x0 + b * y0 == c);
      int a2 = a / g, b2 = b / g;
      int lo = max((INF * b2 + b2 - x0) / b2,
                   (INF * a2 + y0 - num[b] + a2 - 1) / a2) -
               INF;
      int hi =
          min((INF * b2 + num[a] - x0) / b2, (INF * a2 + y0 - 1) / a2) - INF;
      if (lo <= hi)
        s = (s + hi - lo + 1) % MOD;
    }
  }
  cout << s << "\n";
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> P;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(c) (c).begin(), (c).end()
#define uniq(c) c.erase(unique(all(c)), (c).end())
#define index(xs, x) (int)(lower_bound(all(xs), x) - xs.begin())
#define _1 first
#define _2 second
#define pb push_back
#define INF 1145141919LL
#define MOD 1000000007
#define int long long

int modpow(int x, int k) {
  int a = 1;
  while (k > 0) {
    if (k & 1)
      a = (1LL * a * x) % MOD;
    x = (1LL * x * x) % MOD;
    k >>= 1;
  }
  return a;
}
int gcd(int a, int b) {
  if (a > b)
    swap(a, b);
  if (a == 0)
    return b;
  return gcd(b % a, a);
}
int xGCD(int a, int b, int &x, int &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  int x1, y1, gcd = xGCD(b, a % b, x1, y1);
  x = y1;
  y = x1 - (a / b) * y1;
  return gcd;
}

int S;
int num[11];
signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  num[1] = 9;
  for (int i = 2; i <= 10; i++)
    num[i] = 10LL * num[i - 1];

  cin >> S;
  vector<int> ds;
  for (int d = 1; d * d <= S; d++)
    if (S % d == 0)
      ds.pb(d), ds.pb(S / d);
  sort(all(ds));
  uniq(ds);
  int s = 0;
  for (int f : ds) {
    int n = S / f;
    if (f <= 9 && n > num[f])
      continue;
    s = (s + 9LL * modpow(10, f - 1) + 1 + MOD - n) % MOD;
  }
  for (int a = 10; a <= S; a++) {
    int lo = 1 + S / (a + 1), hi = (S - 1) / a;
    if (lo <= hi) {
      s += hi - lo + 1;
      if (s >= MOD)
        s -= MOD;
    }
  }

  for (int a = 1; a <= 10; a++) {
    for (int b = a + 1; b <= 10; b++) {
      int g = gcd(a, b);
      long long c = S;
      for (int x = a + 1; x <= b - 1; x++)
        c -= 1LL * x * num[x];
      if (c <= 0 || c % g)
        continue;
      int x0, y0;
      xGCD(a, b, x0, y0);
      x0 *= c / g;
      y0 *= c / g;
      assert(a * x0 + b * y0 == c);
      int a2 = a / g, b2 = b / g;
      int lo = max((INF * b2 + b2 - x0) / b2,
                   (INF * a2 + y0 - num[b] + a2 - 1) / a2) -
               INF;
      int hi =
          min((INF * b2 + num[a] - x0) / b2, (INF * a2 + y0 - 1) / a2) - INF;
      if (lo <= hi)
        s = (s + hi - lo + 1) % MOD;
    }
  }
  cout << s << "\n";
  return 0;
}