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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MOD 1000000007
#define MAX_N 100000
#define MAX_P 200005
ll fact[MAX_P];
ll extgcd(ll a, ll b, ll &x, ll &y) {
  ll d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}
ll mod_inverse(ll a, ll m) {
  ll x, y;
  extgcd(a, m, x, y);
  return (m + x % m) % m;
}
#define MAX_D 2222
ll dp[MAX_D][MAX_D];
int main() {
  ll n, d, x;
  while (cin >> n >> d >> x, n || d || x) {
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    ll p = 1, ans = 0;
    for (int i = 0; i < min(d, n); i++) {
      ll sum[MAX_D];
      memset(sum, 0, sizeof(sum));
      for (int j = 0; j < n; j++)
        sum[j + 1] = (sum[j] + dp[i][j]) % MOD;
      for (int k = 1; k <= n; k++) {
        dp[i + 1][k] += (MOD + sum[k] - sum[max(0LL, k - x + 1)]) % MOD;
        dp[i + 1][k] %= MOD;
      }
      p *= (d - i) % MOD;
      p %= MOD;
      p *= mod_inverse(i + 1, MOD);
      p %= MOD;
      ans += dp[i + 1][n] * p;
      ans %= MOD;
    }
    /*//
    for(int i=0;i<=n;i++)
      for(int j=0;j<=n;j++)
        cout<<dp[i][j]<<" \\n"[j==n];
    //*/
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MOD 1000000007
#define MAX_P 200005
ll fact[MAX_P];
ll extgcd(ll a, ll b, ll &x, ll &y) {
  ll d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}
ll mod_inverse(ll a, ll m) {
  ll x, y;
  extgcd(a, m, x, y);
  return (m + x % m) % m;
}

typedef pair<ll, ll> P;
#define sum first
#define lazy second
struct lazytree {
  ll N;
  vector<P> node;
  lazytree() {}
  lazytree(ll n) { init(n); }
  void init(ll n) {
    N = 1;
    while (N < n)
      N *= 2;
    node.resize(N * 2 - 1);
  }
  void clear() {
    node.clear();
    node.resize(N * 2 - 1);
  }
  inline void evaluate(ll length, ll k) {
    node[k * 2 + 1].lazy += node[k].lazy;
    node[k * 2 + 1].lazy %= MOD;
    node[k * 2 + 2].lazy += node[k].lazy;
    node[k * 2 + 2].lazy %= MOD;
    node[k].sum += (node[k].lazy * length) % MOD;
    node[k].sum %= MOD;
    node[k].lazy = 0;
  }

  ll add(ll a, ll b, ll v, ll l, ll r, ll k) {
    if (r <= a || b <= l)
      return (node[k].sum + node[k].lazy * (r - l)) % MOD;
    if (a <= l && r <= b)
      return (node[k].sum + (node[k].lazy += v) * (r - l)) % MOD;
    evaluate(r - l, k);
    return node[k].sum = add(a, b, v, l, (l + r) / 2, k * 2 + 1) +
                         add(a, b, v, (l + r) / 2, r, k * 2 + 2) % MOD;
  }

  ll get(ll a, ll b, ll l, ll r, ll k) {
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return (node[k].sum + node[k].lazy * (r - l)) % MOD;
    evaluate(r - l, k);
    return get(a, b, l, (l + r) / 2, k * 2 + 1) +
           get(a, b, (l + r) / 2, r, k * 2 + 2) % MOD;
  }

  void add(ll a, ll b, ll v) { add(a, b, v, 0, N, 0); }
  ll get(ll a, ll b) { return get(a, b, 0, N, 0); }
};

int main() {
  ll n, d, x;
  while (cin >> n >> d >> x, n || d || x) {
    lazytree lt[2];
    lt[0].init(n);
    lt[1].init(n);
    lt[0].add(0, 1, 1);
    ll p = 1, ans = 0;
    for (ll i = 0; i < min(d, n); i++) {
      bool f = i % 2;
      lt[!f].clear();
      for (ll j = 0; j < n; j++)
        lt[!f].add(j + 1, min(j + x, n + 1), lt[f].get(j, j + 1));
      p *= d - i;
      p %= MOD;
      p *= mod_inverse(i + 1, MOD);
      p %= MOD;
      ans += lt[!f].get(n, n + 1) * p;
      ans %= MOD;
    }
    cout << ans << endl;
  }
  return 0;
}