Language: C++

#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <iterator>
#include <numeric>
#include <cstdint>
#include <cmath>
#include <bitset>
#include <string>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <random>
#include <chrono>

#define N_TIMES(i, n)     for ( uint64_t i = 0;     i <  n; ++i )
#define N_TIMES_REV(i, n) for (  int64_t i = n - 1; i >= 0; --i )

template<typename T> using maximum_heap = std::priority_queue<T, std::vector<T>, std::less<T>>;
template<typename T> using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template<typename T>
std::istream& operator>>(std::istream &is, std::vector<T> &v)
{
  for (typename std::vector<T>::size_type i = 0; i < v.size(); ++i) {
    is >> v[i];
  }
  return is;
}

using namespace std;

const uint64_t MOD = 1e+9 + 7;

template<typename T, T MOD = 1e+9 + 7>
struct mod_int_base
{
protected:
  T _val;

public:
  mod_int_base(T val = 0) : _val(val % MOD) {}

  T get() const { return _val; }

  mod_int_base<T, MOD> pow(const T &e) const
  {
    if (e <= 1) {
      return (e == 0) ? mod_int_base<T, MOD>(1) : (*this);
    }

    mod_int_base<T, MOD> w = pow(e >> 1);
    mod_int_base<T, MOD> z = w * w;

    if (e % 2 == 1) { z *= (*this); }

    return z;
  }

  mod_int_base<T, MOD> inv() const { return pow(MOD - 2); }

  bool operator==(const T &rhs) const { return _val == (rhs % MOD); }
  bool operator!=(const T &rhs) const { return _val != (rhs % MOD); }
  bool operator< (const T &rhs) const { return _val <  (rhs % MOD); }
  bool operator<=(const T &rhs) const { return _val <= (rhs % MOD); }
  bool operator> (const T &rhs) const { return _val >  (rhs % MOD); }
  bool operator>=(const T &rhs) const { return _val >= (rhs % MOD); }

  bool operator==(const mod_int_base<T, MOD> &rhs) const { return _val == rhs.get(); }
  bool operator!=(const mod_int_base<T, MOD> &rhs) const { return _val != rhs.get(); }
  bool operator< (const mod_int_base<T, MOD> &rhs) const { return _val <  rhs.get(); }
  bool operator<=(const mod_int_base<T, MOD> &rhs) const { return _val <= rhs.get(); }
  bool operator> (const mod_int_base<T, MOD> &rhs) const { return _val >  rhs.get(); }
  bool operator>=(const mod_int_base<T, MOD> &rhs) const { return _val >= rhs.get(); }

  mod_int_base<T, MOD> operator+(const T &rhs) const {
    return mod_int_base<T, MOD>((_val + (rhs % MOD)) % MOD);
  }
  mod_int_base<T, MOD> operator-(const T &rhs) const {
    return mod_int_base<T, MOD>((_val + (MOD - (rhs % MOD))) % MOD);
  }
  mod_int_base<T, MOD> operator*(const T &rhs) const {
    return mod_int_base<T, MOD>((_val * (rhs % MOD)) % MOD);
  }
  mod_int_base<T, MOD> operator/(const T &rhs) const {
    return mod_int_base<T, MOD>((_val * mod_int_base<T, MOD>(rhs).inv().get()) % MOD);
  }
  mod_int_base<T, MOD> operator+(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val + rhs.get()) % MOD);
  }
  mod_int_base<T, MOD> operator-(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val + (MOD - rhs.get())) % MOD);
  }
  mod_int_base<T, MOD> operator*(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val * rhs.get()) % MOD);
  }
  mod_int_base<T, MOD> operator/(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val * rhs.inv().get()) % MOD);
  }

  mod_int_base<T, MOD>& operator+=(const T &rhs) {
    _val = (_val + (rhs % MOD)) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator-=(const T &rhs) {
    _val = (_val + (MOD - (rhs % MOD))) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator*=(const T &rhs) {
    _val = (_val * (rhs % MOD)) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator/=(const T &rhs) {
    _val = (_val * mod_int_base<T, MOD>(rhs).inv().get()) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator+=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val + rhs.get()) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator-=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val + (MOD - rhs.get())) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator*=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val * rhs.get()) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator/=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val * rhs.inv().get()) % MOD;
    return *this;
  }
};

template<uint64_t MOD = 1e+9 + 7>
struct mod_uint64_t_base : public mod_int_base<uint64_t, MOD>
{
public:
  mod_uint64_t_base(uint64_t n = 0) : mod_int_base<uint64_t, MOD>(n) {}
  mod_uint64_t_base(const mod_int_base<uint64_t, MOD> &n) : mod_int_base<uint64_t, MOD>(n) {}  

  operator uint64_t () const { return this->get(); }

  mod_uint64_t_base<MOD>& operator=(const mod_uint64_t_base<MOD> &rhs) { 
    this->_val = rhs.get();
    return *this;
  }
  mod_uint64_t_base<MOD>& operator=(const uint64_t &rhs) {
    this->_val = rhs % MOD;
    return *this;
  }

  mod_uint64_t_base<MOD> operator+(const int64_t &rhs) const {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    return mod_uint64_t_base<MOD>(this->_val + _rhs);
  }
  mod_uint64_t_base<MOD> operator-(const int64_t &rhs) const {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    return mod_uint64_t_base<MOD>((MOD + this->_val) - _rhs);
  }
  mod_uint64_t_base<MOD> operator*(const int64_t &rhs) const {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    return mod_uint64_t_base<MOD>(this->_val * _rhs);
  }
  mod_uint64_t_base<MOD> operator/(const int64_t &rhs) const {
    mod_uint64_t_base<MOD> _rhs = mod_uint64_t_base<MOD>(rhs % MOD);
    return mod_uint64_t_base<MOD>(this->_val * _rhs.inv());
  }

  mod_uint64_t_base<MOD> operator+(const mod_uint64_t_base<MOD> &rhs) const {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    return mod_uint64_t_base<MOD>(this->_val + _rhs);
  }
  mod_uint64_t_base<MOD> operator-(const mod_uint64_t_base<MOD> &rhs) const {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    return mod_uint64_t_base<MOD>((MOD + this->_val) - _rhs);
  }
  mod_uint64_t_base<MOD> operator*(const mod_uint64_t_base<MOD> &rhs) const {
    return mod_uint64_t_base<MOD>(this->_val * rhs.get());
  }
  mod_uint64_t_base<MOD> operator/(const mod_uint64_t_base<MOD> &rhs) const {
    return mod_uint64_t_base<MOD>(this->_val * rhs.inv());
  }

  mod_uint64_t_base<MOD>& operator=(const int64_t &rhs) {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    this->_val = _rhs;
    return *this;
  }
  mod_uint64_t_base<MOD>& operator+=(const int64_t &rhs) {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    this->_val = (this->_val + _rhs) % MOD;
    return *this;
  }
  mod_uint64_t_base<MOD>& operator-=(const int64_t &rhs) {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    this->_val = ((MOD + this->_val) - _rhs) % MOD;
    return *this;
  }
  mod_uint64_t_base<MOD>& operator*=(const int64_t &rhs) {
    uint64_t _rhs = static_cast<uint64_t>(MOD + rhs) % MOD;
    this->_val = (this->_val * _rhs) % MOD;
    return *this;
  }
};

typedef mod_uint64_t_base<MOD> m_uint64_t;

std::istream& operator>>(std::istream& is, m_uint64_t &v)
{
  uint64_t u;
  is >> u;
  v = m_uint64_t(u);
  return is;
}

std::ostream& operator<<(std::ostream& os, const m_uint64_t &v)
{
  os << v.get();
  return os;
}

template<typename ModInt = m_uint64_t>
class CombinationBase
{
private:
  std::vector<ModInt> _memo;

  void _initialize(uint64_t N) {
    _memo = std::vector<ModInt>(N + 1);
    _memo[0] = ModInt(1);

    for (uint64_t n = 1; n <= N; n += 1) {
      _memo[n] = ModInt(n) * _memo[n - 1];
    }
    debug(_memo);
  }

public:
  CombinationBase() {}
  CombinationBase(uint64_t N) { _initialize(N); }

  void initialize(uint64_t N) { _initialize(N); }

  ModInt fact(uint64_t n) const { return _memo[n]; }
  ModInt perm(uint64_t n, uint64_t k) const {
    return _memo[n] / _memo[k];
  }
  ModInt comb(uint64_t n, uint64_t k) const {
    debug(make_tuple(_memo[n], _memo[k], _memo[n - k]));
    debug((_memo[k] * _memo[n - k]).inv());
    return _memo[n] * (_memo[k] * _memo[n - k]).inv();
  }

  ModInt perm_rep(uint64_t a, uint64_t b) const {
    uint64_t n = a + b;
    return _memo[n] / (_memo[a] * _memo[b]);
  }
  ModInt comb_rep(uint64_t n, uint64_t k) const {
    return comb(n + k - 1, k);
  }
};

typedef CombinationBase<m_uint64_t> Combination;

int main()
{
  uint64_t S;
  cin >> S;

  if (S <= 2) {
    cout << 0 << endl;
    return 0;
  }

  m_uint64_t T = 0;
  uint64_t N = S / 3;
  Combination comb(S + 1);
  for (uint64_t n = 1; n <= N; ++n) {
    uint64_t s = S - (3 * n);
    T += comb.comb_rep(n, s);
  }
  cout << T << endl;

  return 0;
}

Compiler output:
a.cc: In instantiation of 'void CombinationBase<ModInt>::_initialize(uint64_t) [with ModInt = mod_uint64_t_base<1000000007>; uint64_t = long unsigned int]':
a.cc:246:33:   required from 'CombinationBase<ModInt>::CombinationBase(uint64_t) [with ModInt = mod_uint64_t_base<1000000007>; uint64_t = long unsigned int]'
  246 |   CombinationBase(uint64_t N) { _initialize(N); }
      |                                 ^~~~~~~~~~~
a.cc:283:25:   required from here
  283 |   Combination comb(S + 1);
      |                         ^
a.cc:241:10: error: 'debug' was not declared in this scope
  241 |     debug(_memo);
      |     ~~~~~^~~~~~~
a.cc: In instantiation of 'ModInt CombinationBase<ModInt>::comb(uint64_t, uint64_t) const [with ModInt = mod_uint64_t_base<1000000007>; uint64_t = long unsigned int]':
a.cc:265:12:   required from 'ModInt CombinationBase<ModInt>::comb_rep(uint64_t, uint64_t) const [with ModInt = mod_uint64_t_base<1000000007>; uint64_t = long unsigned int]'
  265 |     return comb(n + k - 1, k);
      |            ^~~~
a.cc:286:23:   required from here
  286 |     T += comb.comb_rep(n, s);
      |          ~~~~~~~~~~~~~^~~~~~
a.cc:255:10: error: 'debug' was not declared in this scope
  255 |     debug(make_tuple(_memo[n], _memo[k], _memo[n - k]));
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:256:10: error: 'debug' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation
  256 |     debug((_memo[k] * _memo[n - k]).inv());
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:255:10: note: 'debug' declared here, later in the translation unit
  255 |     debug(make_tuple(_memo[n], _memo[k], _memo[n - k]));
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~