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

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr char newl = '\\n';

// https://noshi91.hatenablog.com/entry/2019/03/31/174006
template <std::uint_fast64_t Modulus> struct ModInt {
  using u64 = std::uint_fast64_t;

  static constexpr u64 MOD = Modulus;

  u64 val;

  constexpr ModInt(const u64 x = 0) noexcept : val(x % MOD) {}

  constexpr ModInt operator+() const noexcept { return ModInt(*this); }
  constexpr ModInt operator-() const noexcept {
    ModInt res(*this);
    if (res.val != 0)
      res.val = MOD - res.val;
    return res;
  }

  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return val == rhs.val;
  }
  constexpr bool operator!=(const ModInt &rhs) const noexcept {
    return val != rhs.val;
  }

  // prefix increment/decrement
  constexpr ModInt &operator++() noexcept { return *this += ModInt(1); }
  constexpr ModInt &operator--() noexcept { return *this -= ModInt(1); }

  // postfix increment/decrement
  constexpr ModInt operator++(int) noexcept {
    ModInt tmp(*this);
    ++*this;
    return tmp;
  }
  constexpr ModInt operator--(int) noexcept {
    ModInt tmp(*this);
    --*this;
    return tmp;
  }

  constexpr ModInt operator+(const ModInt &rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt &rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt &rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt &rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }

  constexpr ModInt &operator+=(const ModInt &rhs) noexcept {
    val += rhs.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt &rhs) noexcept {
    if (val < rhs.val)
      val += MOD;
    val -= rhs.val;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt &rhs) noexcept {
    val = val * rhs.val % MOD;
    return *this;
  }

  // prime Modulus only
  constexpr ModInt &operator/=(const ModInt &rhs) noexcept {
    return *this *= rhs.inv();
  }

  // prime Modulus only
  constexpr ModInt inv() const noexcept { return pow(*this, MOD - 2); }
};

template <std::uint_fast64_t Modulus>
constexpr ModInt<Modulus> pow(ModInt<Modulus> x, std::uint_fast64_t n) {
  ModInt<Modulus> res(1);
  while (n) {
    if (n & 1)
      res *= x;
    x *= x;
    n >>= 1;
  }
  return res;
}

template <std::uint_fast64_t Modulus>
istream &operator>>(istream &is, ModInt<Modulus> &x) {
  std::uint_fast64_t val;
  is >> val;
  x = ModInt<Modulus>(val);
  return is;
}

template <std::uint_fast64_t Modulus>
ostream &operator<<(ostream &os, const ModInt<Modulus> &x) {
  return os << x.val;
}

using mint = ModInt<1000000007>;

using Poly = vector<mint>;

// return p(x) q(-x)
inline Poly mul(const Poly &p, const Poly &q) noexcept {
  int sz_p = p.size(), sz_q = q.size();
  Poly res(sz_p + sz_q - 1, 0);

  for (int i = 0; i < sz_p; i++) {
    for (int j = 0; j < sz_q; j++) {
      res[i + j] += p[i] * q[j];
    }
  }
  return res;
}

inline Poly even(const Poly &p) noexcept {
  int sz = p.size();
  Poly res((sz + 1) / 2, 0);

  for (int i = 0; i < sz; i += 2) {
    res[i >> 1] = p[i];
  }
  return res;
}

inline Poly odd(const Poly &p) noexcept {
  int sz = p.size();
  Poly res(sz / 2, 0);

  for (int i = 1; i < sz; i += 2) {
    res[(i - 1) >> 1] = p[i];
  }
  return res;
}

// return p(x) q(-x)
inline Poly mul_pn(const Poly &p, const Poly &q) noexcept {
  int sz_p = p.size(), sz_q = q.size();
  Poly res(sz_p + sz_q - 1, 0);

  for (int i = 0; i < sz_p; i++) {
    for (int j = 0; j < sz_q; j++) {
      res[i + j] += p[i] * ((j & 1) ? -q[j] : q[j]);
    }
  }
  return res;
}

// http://q.c.titech.ac.jp/docs/progs/polynomial_division.html
mint calc(Poly p, Poly q, ll n) {
  while (n > 0) {
    if (n & 1)
      p = odd(mul_pn(p, q));
    else
      p = even(mul_pn(p, q));

    q = even(mul_pn(q, q));
    n >>= 1;
  }
  return p[0];
}

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  const Poly f1 = {1, mint::MOD - 1};
  const Poly f2 = {1, 1};

  Poly p = {0, 0, 0, 0, 0, 1};
  Poly q = f1;

  for (int i = 0; i < 15; i++) {
    q = mul(q, f1);
  }

  for (int i = 0; i < 5; i++) {
    q = mul(q, f2);
  }

  int t;
  cin >> t;

  for (int i = 0; i < t; i++) {
    ll n;
    cin >> n;
    cout << calc(p, q, n) << newl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

constexpr char newl = '\\n';

// https://noshi91.hatenablog.com/entry/2019/03/31/174006
template <std::uint_fast64_t Modulus> struct ModInt {
  using u64 = std::uint_fast64_t;

  static constexpr u64 MOD = Modulus;

  u64 val;

  constexpr ModInt(const u64 x = 0) noexcept : val(x % MOD) {}

  constexpr ModInt operator+() const noexcept { return ModInt(*this); }
  constexpr ModInt operator-() const noexcept {
    ModInt res(*this);
    if (res.val != 0)
      res.val = MOD - res.val;
    return res;
  }

  constexpr bool operator==(const ModInt &rhs) const noexcept {
    return val == rhs.val;
  }
  constexpr bool operator!=(const ModInt &rhs) const noexcept {
    return val != rhs.val;
  }

  // prefix increment/decrement
  constexpr ModInt &operator++() noexcept { return *this += ModInt(1); }
  constexpr ModInt &operator--() noexcept { return *this -= ModInt(1); }

  // postfix increment/decrement
  constexpr ModInt operator++(int) noexcept {
    ModInt tmp(*this);
    ++*this;
    return tmp;
  }
  constexpr ModInt operator--(int) noexcept {
    ModInt tmp(*this);
    --*this;
    return tmp;
  }

  constexpr ModInt operator+(const ModInt &rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt &rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt &rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt &rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }

  constexpr ModInt &operator+=(const ModInt &rhs) noexcept {
    val += rhs.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt &rhs) noexcept {
    if (val < rhs.val)
      val += MOD;
    val -= rhs.val;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt &rhs) noexcept {
    val = val * rhs.val % MOD;
    return *this;
  }

  // prime Modulus only
  constexpr ModInt &operator/=(const ModInt &rhs) noexcept {
    return *this *= rhs.inv();
  }

  // prime Modulus only
  constexpr ModInt inv() const noexcept { return pow(*this, MOD - 2); }
};

template <std::uint_fast64_t Modulus>
constexpr ModInt<Modulus> pow(ModInt<Modulus> x, std::uint_fast64_t n) {
  ModInt<Modulus> res(1);
  while (n) {
    if (n & 1)
      res *= x;
    x *= x;
    n >>= 1;
  }
  return res;
}

template <std::uint_fast64_t Modulus>
istream &operator>>(istream &is, ModInt<Modulus> &x) {
  std::uint_fast64_t val;
  is >> val;
  x = ModInt<Modulus>(val);
  return is;
}

template <std::uint_fast64_t Modulus>
ostream &operator<<(ostream &os, const ModInt<Modulus> &x) {
  return os << x.val;
}

using mint = ModInt<1000000007>;

mint calc1(ll i) {
  ll cnt = i / 2 + 1;
  ll last = i - (cnt - 1) * 2;
  mint sum = mint(i + last) * cnt / 2;
  return sum;
}

const mint inv2 = mint(960).inv();

// https://oeis.org/A028346
constexpr mint calc2(ll i) noexcept {
  if (i <= 1)
    return 0;
  mint n = i - 2;
  mint res = n * n * n * n * 2;
  res += n * n * n * 32;
  res += n * n * 172;
  res += n * 352;
  res += 225;
  if (i & 1)
    res -= 15;
  else
    res += 15;
  res *= n + 4;
  res *= inv2;
  return res;
}

const mint inv3 = mint(11612160).inv();

// https://oeis.org/A054497
constexpr mint solve3(ll n) noexcept {
  if (n <= 2)
    return 0;
  mint n2 = n - 3;

  mint res = 0;
  mint np = 1;
  {
    mint hoge = 4017;
    if (n & 1)
      hoge += 79;
    else
      hoge -= 79;
    hoge *= 2835;
    res += hoge * np;
    np *= n2;
  }

  {
    mint hoge = 1513217;
    if (n & 1)
      hoge += 4095;
    else
      hoge -= 4095;
    hoge *= 18;
    res += hoge * np;
    np *= n2;
  }

  {
    mint hoge = 284609;
    if (n & 1)
      hoge += 63;
    else
      hoge -= 63;
    hoge *= 90;
    res += hoge * np;
    np *= n2;
  }

  res += np * 12771104;
  np *= n2;

  res += np * 3787056;
  np *= n2;

  res += np * 701400;
  np *= n2;

  res += np * 81900;
  np *= n2;

  res += np * 5856;
  np *= n2;

  res += np * 234;
  np *= n2;

  res += np * 4;
  res *= inv3;
  return res;
}

mint solve_small(int num, ll n) {
  if (num == 0)
    return 1;
  if (num == 1) {
    // https://oeis.org/A002623
    __int128_t tmp = (n + 1);
    tmp = tmp * (n + 3) * (2 * n + 1) / 24;
    return mint(tmp % mint::MOD);
  }

  /*
  if (num == 2) {
      // https://oeis.org/A299335
      __int128_t n2 = n - 1;
      __int128_t res = 2 * n2 * n2 * n2 * n2 * n2 * n2;
      res += 54 * n2 * n2 * n2 * n2 * n2;
      res += 575 * n2 * n2 * n2 * n2;
      res += 3060 * n2 * n2 * n2;
      res += 8468 * n2 * n2;
      if (n2 & 1) {
          res += 11286 * n2;
          res += 5355;
      } else {
          res += 11376 * n2;
          res += 5760;
      }
      res /= 5760;
      return mint(res % mint::MOD);
  }*/

  mint res = 0;
  for (ll i = 0; i <= n; i++) {
    res += solve3(n - i) * calc2(i);
  }
  return res;
}

mint solve_medium(ll n) {
  mint res = 0;
  for (ll i = 0; i <= n; i++) {
    res += solve3(n - i) * calc2(i);
  }
  return res;
}

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  int t;
  cin >> t;

  for (int i = 0; i < t; i++) {
    ll n;
    cin >> n;
    cout << solve_medium(n) << newl;
  }

  return 0;
}