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

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
const int MOD = 1e9 + 7;
int sm[10050];
int dp[5050][5050];
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int n, m, k, q;
  cin >> n >> m >> k >> q;
  memset(dp, 0, sizeof(dp));
  dp[0][0] = 1;
  for (int i = 0; i < m; i++) {
    memset(sm, 0, sizeof(sm));
    for (int j = 0; j < n; j++) {
      int x = j % (2 * k);
      sm[x] += dp[i][j];
      sm[x] %= MOD;
      sm[2 * k + x] += dp[i][j];
      sm[2 * k + x] %= MOD;
    }

    for (int j = 1; j < 4 * k; j++)
      sm[j] = (sm[j] + sm[j - 1]) % MOD;

    for (int j = 0; j < n; j++)
      dp[i + 1][j] =
          (sm[2 * k + (j % (2 * k))] + MOD - sm[k + (j % (2 * k))]) % MOD;
  }

  for (int i = 0; i < q; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    int d = (c - a + n) % n;
    cout << dp[b][d] << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
using namespace boost::math::constants;

using namespace std;
using Int = long long;
#define int long long
#define MOD 1000000007
#define rep(i, n) for (Int i = 0; i < (Int)(n); i++)
using namespace boost::multiprecision;

namespace FFT {
using dbl = number<cpp_dec_float<64>>;
const dbl PI = pi<dbl>();

struct num {
  dbl x, y;
  num() { x = y = 0; }
  num(dbl x, dbl y) : x(x), y(y) {}
};

inline num operator+(num a, num b) { return num(a.x + b.x, a.y + b.y); }
inline num operator-(num a, num b) { return num(a.x - b.x, a.y - b.y); }
inline num operator*(num a, num b) {
  return num(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
}
inline num conj(num a) { return num(a.x, -a.y); }

Int base = 1;
vector<num> rts = {{0, 0}, {1, 0}};
vector<Int> rev = {0, 1};

void ensure_base(Int nbase) {
  if (nbase <= base)
    return;

  rev.resize(1 << nbase);
  for (Int i = 0; i < (1 << nbase); i++)
    rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));

  rts.resize(1 << nbase);
  while (base < nbase) {
    dbl angle = dbl(2 * PI) / dbl(1 << (base + 1));
    for (Int i = 1 << (base - 1); i < (1 << base); i++) {
      rts[i << 1] = rts[i];
      dbl angle_i = angle * dbl(2 * i + 1 - (1 << base));
      rts[(i << 1) + 1] = num(cos(angle_i), sin(angle_i));
    }
    base++;
  }
}

void fft(vector<num> &a, Int n = -1) {
  if (n == -1)
    n = a.size();
  assert((n & (n - 1)) == 0);

  Int zeros = __builtin_ctz(n);
  ensure_base(zeros);
  Int shift = base - zeros;
  for (Int i = 0; i < n; i++)
    if (i < (rev[i] >> shift))
      swap(a[i], a[rev[i] >> shift]);

  for (Int k = 1; k < n; k <<= 1) {
    for (Int i = 0; i < n; i += 2 * k) {
      for (Int j = 0; j < k; j++) {
        num z = a[i + j + k] * rts[j + k];
        a[i + j + k] = a[i + j] - z;
        a[i + j] = a[i + j] + z;
      }
    }
  }
}

vector<num> fa;

vector<Int> multiply(vector<Int> &a, vector<Int> &b) {
  Int need = a.size() + b.size() - 1;
  Int nbase = 0;
  while ((1 << nbase) < need)
    nbase++;
  ensure_base(nbase);

  Int sz = 1 << nbase;
  if (sz > (Int)fa.size())
    fa.resize(sz);
  for (Int i = 0; i < sz; i++) {
    Int x = (i < (Int)a.size() ? a[i] : 0);
    Int y = (i < (Int)b.size() ? b[i] : 0);
    fa[i] = num(x, y);
  }
  fft(fa, sz);

  num r(0, -0.25 / sz);
  for (Int i = 0; i <= (sz >> 1); i++) {
    Int j = (sz - i) & (sz - 1);
    num z = (fa[j] * fa[j] - conj(fa[i] * fa[i])) * r;
    if (i != j)
      fa[j] = (fa[i] * fa[i] - conj(fa[j] * fa[j])) * r;
    fa[i] = z;
  }
  fft(fa, sz);

  vector<Int> res(need);
  for (Int i = 0; i < need; i++)
    res[i] = round(fa[i].x.convert_to<long double>());

  return res;
}

}; // namespace FFT
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);

  Int n, m, k, q;
  cin >> n >> m >> k >> q;

  vector<Int> v(n, 0);
  for (Int j = 0; j < n; j++)
    v[j] = ((j / k) % 2 == 0);
  vector<Int> dp(n, 0);
  dp[0] = 1;
  Int p = 0;

  auto calc = [&]() {
    p++;
    auto nx = FFT::multiply(dp, v);
    for (Int i = 0; i < n; i++)
      dp[i] = 0;
    for (Int i = 0; i < (Int)nx.size(); i++)
      dp[i % n] += nx[i];
    for (Int i = 0; i < n; i++)
      dp[i] %= MOD;
  };

  using T = tuple<Int, Int, Int>;
  vector<T> ans(q);
  for (Int i = 0; i < q; i++) {
    Int a, b, c;
    cin >> a >> b >> c;
    ans[i] = T(b, (c + n - a) % n, i);
  }
  sort(ans.begin(), ans.end());
  vector<Int> pri(q);
  for (Int i = 0; i < q; i++) {
    Int b, l, idx;
    tie(b, l, idx) = ans[i];
    while (p < b)
      calc();
    pri[idx] = dp[l];
  }
  for (Int i = 0; i < q; i++)
    cout << pri[i] << endl;
  return 0;
}