Problem p03096 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

const long long MOD = 1000000007;

typedef long long
    ll; // -9,223,372,036,854,775,808 から 9,223,372,036,854,775,807

template <class T> using vec = std::vector<T>;
template <class T> using vec2 = vec<vec<T>>;
template <class T> using vec3 = vec<vec<vec<T>>>;

// #define DEBUG

struct GCDResult {
  long long x;
  long long y;
  long long res;
};
GCDResult gcd(long long a, long long b) {
  if (a < 0) {
    auto sub = gcd(-a, b);
    return GCDResult{-sub.x, sub.y, sub.res};
  }
  if (b < 0) {
    auto sub = gcd(a, -b);
    return GCDResult{sub.x, -sub.y, sub.res};
  }
  if (a < b) {
    auto sub = gcd(b, a);
    return GCDResult{sub.y, sub.x, sub.res};
  }
  // a >= b AND a >= 0 AND b >= 0
  if (b == 0) {
    return GCDResult{1LL, 0LL, a};
  }
  // a >= b AND a > 0 AND b > 0
  auto sub = gcd(b, a % b);
  return GCDResult{sub.y, sub.x - sub.y * (a / b), sub.res};
}

// Requires ATC_GCD
const int COM_MAX = 510000;
template <long long p> class Zp {
  long long content;

  // for comb()
  static array<long long, COM_MAX> fac;
  static array<long long, COM_MAX> finv;
  static array<long long, COM_MAX> inv_;
  static bool is_initialized_com_table;

  // By rng_2 (See https://drken1215.hatenablog.com/entry/2018/06/08/210000)
  // テーブルを作る前処理
  static void COMinit() {
    auto MOD = p;
    auto MAX = COM_MAX;
    fac.at(0) = fac.at(1) = 1;
    finv.at(0) = finv.at(1) = 1;
    inv_.at(1) = 1;
    for (int i = 2; i < MAX; i++) {
      fac.at(i) = fac.at(i - 1) * i % MOD;
      inv_.at(i) = MOD - inv_.at(MOD % i) * (MOD / i) % MOD;
      finv.at(i) = finv.at(i - 1) * inv_.at(i) % MOD;
    }
    is_initialized_com_table = true;
  }

  // 二項係数計算
  static long long COM(int n, int k) {
    auto MOD = p;
    auto MAX = COM_MAX;
    if (!is_initialized_com_table) {
      assert(false);
    }
    if (n < k)
      return 0;
    if (n < 0 || k < 0)
      return 0;
    return fac.at(n) * (finv.at(k) * finv.at(n - k) % MOD) % MOD;
  }

public:
  Zp(long long content_) {
    if (content_ >= 0) {
      content = content_ % p;
    } else {
      long long temp = p;
      while (temp < -content_) {
        temp *= p;
      }
      content = (temp + content_) % p;
    }
  }

  bool operator==(const Zp<p> &rhs) const {
    return this->content == rhs.content;
  }

  bool operator!=(const Zp<p> &rhs) const { return !(*this == rhs); }

  Zp<p> operator+(const Zp<p> &rhs) const {
    return Zp<p>(this->content + rhs.content);
  }

  Zp<p> operator-() const { return Zp<p>(p - this->content); }

  Zp<p> operator-(const Zp<p> &rhs) const {
    return Zp<p>(this->content - rhs.content + p);
  }

  Zp<p> operator*(const Zp<p> &rhs) const {
    return Zp<p>(this->content * rhs.content);
  }

  Zp<p> inv() const {
    if (this->content == 0) {
      assert(false);
    }

    auto res = gcd(this->content, p);
    return Zp<p>(res.x);
  }

  Zp<p> operator/(const Zp<p> &rhs) const {
    if (rhs.content == 0) {
      assert(false);
    }

    return (*this) * rhs.inv();
  }

  Zp<p> pow(int n) {
    auto res = Zp<p>(1);
    Zp<p> mult = (*this);
    while (n > 0) {
      if (n & 1 == 1) {
        res = res * mult;
      }
      n >>= 1;
      mult = mult * mult;
    }
    return res;
  }

  void operator+=(const Zp<p> &rhs) { *this = *this + rhs; }

  void operator-=(const Zp<p> &rhs) { *this = *this - rhs; }

  void operator*=(const Zp<p> &rhs) { *this = *this * rhs; }

  void operator/=(const Zp<p> &rhs) { *this = *this / rhs; }

  long long raw() { return this->content; }

  static void initializeCom() { COMinit(); }

  static Zp<p> com(int n, int k) { return Zp<p>(COM(n, k)); }
};

template <long long p> bool Zp<p>::is_initialized_com_table = false;
template <long long p> array<long long, COM_MAX> Zp<p>::fac;
template <long long p> array<long long, COM_MAX> Zp<p>::finv;
template <long long p> array<long long, COM_MAX> Zp<p>::inv_;

struct Seq {
  ll len;
  ll col;
};

void solve(long long N, std::vector<long long> C) {
  // shift
  for (auto &iter : C) {
    iter--;
  }

  // かたまりをかぞえる
  vec<Seq> seqs;
  seqs.push_back(Seq{0, C.at(0)});
  for (int i = 0; i < N; i++) {
    if (C.at(i) == seqs.back().col) {
      seqs.back().len++;
    } else {
      seqs.push_back(Seq{1, C.at(i)});
    }
  }

  // かたまりの個数をかぞえる
  vec<ll> cnt(200'000);
  for (auto iter : seqs) {
    cnt.at(iter.col)++;
  }

  vec<Zp<MOD>> resAt(seqs.size(), Zp<MOD>(0));
  ll INF = 11234567LL;
  resAt.at(0) = Zp<MOD>(1);
  vec<ll> lastAppeared(seqs.size(), INF);
  lastAppeared.at(seqs.at(0).col) = 0;
  for (int i = 1; i < seqs.size(); i++) {
    auto res = resAt.at(i - 1);
    if (lastAppeared.at(seqs.at(i).col) != INF) {
      res += resAt.at(lastAppeared.at(seqs.at(i).col));
    }
    resAt.at(i) = res;
    lastAppeared.at(seqs.at(i).col) = i;
  }

  cout << resAt.back().raw() << endl;
}

// Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You
// use the default template now. You can remove this line by using your custom
// template)
int main() {
  long long N;
  scanf("%lld", &N);
  std::vector<long long> C(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &C[i]);
  }
  solve(N, std::move(C));
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const long long MOD = 1000000007;

typedef long long
    ll; // -9,223,372,036,854,775,808 から 9,223,372,036,854,775,807

template <class T> using vec = std::vector<T>;
template <class T> using vec2 = vec<vec<T>>;
template <class T> using vec3 = vec<vec<vec<T>>>;

// #define DEBUG

struct GCDResult {
  long long x;
  long long y;
  long long res;
};
GCDResult gcd(long long a, long long b) {
  if (a < 0) {
    auto sub = gcd(-a, b);
    return GCDResult{-sub.x, sub.y, sub.res};
  }
  if (b < 0) {
    auto sub = gcd(a, -b);
    return GCDResult{sub.x, -sub.y, sub.res};
  }
  if (a < b) {
    auto sub = gcd(b, a);
    return GCDResult{sub.y, sub.x, sub.res};
  }
  // a >= b AND a >= 0 AND b >= 0
  if (b == 0) {
    return GCDResult{1LL, 0LL, a};
  }
  // a >= b AND a > 0 AND b > 0
  auto sub = gcd(b, a % b);
  return GCDResult{sub.y, sub.x - sub.y * (a / b), sub.res};
}

// Requires ATC_GCD
const int COM_MAX = 510000;
template <long long p> class Zp {
  long long content;

  // for comb()
  static array<long long, COM_MAX> fac;
  static array<long long, COM_MAX> finv;
  static array<long long, COM_MAX> inv_;
  static bool is_initialized_com_table;

  // By rng_2 (See https://drken1215.hatenablog.com/entry/2018/06/08/210000)
  // テーブルを作る前処理
  static void COMinit() {
    auto MOD = p;
    auto MAX = COM_MAX;
    fac.at(0) = fac.at(1) = 1;
    finv.at(0) = finv.at(1) = 1;
    inv_.at(1) = 1;
    for (int i = 2; i < MAX; i++) {
      fac.at(i) = fac.at(i - 1) * i % MOD;
      inv_.at(i) = MOD - inv_.at(MOD % i) * (MOD / i) % MOD;
      finv.at(i) = finv.at(i - 1) * inv_.at(i) % MOD;
    }
    is_initialized_com_table = true;
  }

  // 二項係数計算
  static long long COM(int n, int k) {
    auto MOD = p;
    auto MAX = COM_MAX;
    if (!is_initialized_com_table) {
      assert(false);
    }
    if (n < k)
      return 0;
    if (n < 0 || k < 0)
      return 0;
    return fac.at(n) * (finv.at(k) * finv.at(n - k) % MOD) % MOD;
  }

public:
  Zp(long long content_) {
    if (content_ >= 0) {
      content = content_ % p;
    } else {
      long long temp = p;
      while (temp < -content_) {
        temp *= p;
      }
      content = (temp + content_) % p;
    }
  }

  bool operator==(const Zp<p> &rhs) const {
    return this->content == rhs.content;
  }

  bool operator!=(const Zp<p> &rhs) const { return !(*this == rhs); }

  Zp<p> operator+(const Zp<p> &rhs) const {
    return Zp<p>(this->content + rhs.content);
  }

  Zp<p> operator-() const { return Zp<p>(p - this->content); }

  Zp<p> operator-(const Zp<p> &rhs) const {
    return Zp<p>(this->content - rhs.content + p);
  }

  Zp<p> operator*(const Zp<p> &rhs) const {
    return Zp<p>(this->content * rhs.content);
  }

  Zp<p> inv() const {
    if (this->content == 0) {
      assert(false);
    }

    auto res = gcd(this->content, p);
    return Zp<p>(res.x);
  }

  Zp<p> operator/(const Zp<p> &rhs) const {
    if (rhs.content == 0) {
      assert(false);
    }

    return (*this) * rhs.inv();
  }

  Zp<p> pow(int n) {
    auto res = Zp<p>(1);
    Zp<p> mult = (*this);
    while (n > 0) {
      if (n & 1 == 1) {
        res = res * mult;
      }
      n >>= 1;
      mult = mult * mult;
    }
    return res;
  }

  void operator+=(const Zp<p> &rhs) { *this = *this + rhs; }

  void operator-=(const Zp<p> &rhs) { *this = *this - rhs; }

  void operator*=(const Zp<p> &rhs) { *this = *this * rhs; }

  void operator/=(const Zp<p> &rhs) { *this = *this / rhs; }

  long long raw() { return this->content; }

  static void initializeCom() { COMinit(); }

  static Zp<p> com(int n, int k) { return Zp<p>(COM(n, k)); }
};

template <long long p> bool Zp<p>::is_initialized_com_table = false;
template <long long p> array<long long, COM_MAX> Zp<p>::fac;
template <long long p> array<long long, COM_MAX> Zp<p>::finv;
template <long long p> array<long long, COM_MAX> Zp<p>::inv_;

struct Seq {
  ll len;
  ll col;
};

void solve(long long N, std::vector<long long> C) {
  // shift
  for (auto &iter : C) {
    iter--;
  }

  // かたまりをかぞえる
  vec<Seq> seqs;
  seqs.push_back(Seq{0, C.at(0)});
  for (int i = 0; i < N; i++) {
    if (C.at(i) == seqs.back().col) {
      seqs.back().len++;
    } else {
      seqs.push_back(Seq{1, C.at(i)});
    }
  }

  // かたまりの個数をかぞえる
  vec<ll> cnt(200'000);
  for (auto iter : seqs) {
    cnt.at(iter.col)++;
  }

  vec<Zp<MOD>> resAt(seqs.size(), Zp<MOD>(0));
  ll INF = 11234567LL;
  resAt.at(0) = Zp<MOD>(1);
  vec<ll> lastAppeared(200'000, INF);
  lastAppeared.at(seqs.at(0).col) = 0;
  for (int i = 1; i < seqs.size(); i++) {
    auto res = resAt.at(i - 1);
    if (lastAppeared.at(seqs.at(i).col) != INF) {
      res += resAt.at(lastAppeared.at(seqs.at(i).col));
    }
    resAt.at(i) = res;
    lastAppeared.at(seqs.at(i).col) = i;
  }

  cout << resAt.back().raw() << endl;
}

// Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You
// use the default template now. You can remove this line by using your custom
// template)
int main() {
  long long N;
  scanf("%lld", &N);
  std::vector<long long> C(N);
  for (int i = 0; i < N; i++) {
    scanf("%lld", &C[i]);
  }
  solve(N, std::move(C));
  return 0;
}