Problem p02726 (C++) — buggy submission, verdict: Runtime Error

/*
このコード、と～おれ!
Be accepted!
∧＿∧　
（｡･ω･｡)つ━☆・*。
⊂　　 ノ 　　　・゜+.
　しーＪ　　　°。+ *´¨)
 　　　　　　　　　.· ´¸.·*´¨) ¸.·*¨)
                  　　　　　　　　　　(¸.·´ (¸.·'* ☆
*/

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
/*多倍長整数/cpp_intで宣言
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
*/

#pragma gcc target("avx2")
#pragma gcc optimization("o3")
#pragma gcc optimization("unroll-loops")
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define rep2(i, n) for (int i = 2; i < (n); ++i)
#define repr(i, n) for (int i = n; i >= 0; --i)
#define reprm(i, n) for (int i = n - 1; i >= 0; --i)
#define printynl(a) printf(a ? "yes\\n" : "no\\n")
#define printyn(a) printf(a ? "Yes\\n" : "No\\n")
#define printYN(a) printf(a ? "YES\\n" : "NO\\n")
#define printim(a) printf(a ? "possible\\n" : "imposible\\n")
#define printdb(a) printf("%.50lf\\n", a)    // 少数出力
#define printLdb(a) printf("%.50Lf\\n", a)   // 少数出力
#define printdbd(a) printf("%.16lf\\n", a)   // 少数出力(桁少なめ)
#define prints(s) printf("%s\\n", s.c_str()) // string出力
#define all(x) (x).begin(), (x).end()
#define allsum(a, b, c) ((a + b) * c / 2.0) // 等差数列の和、初項,末項,項数
#define pb push_back
#define priq priority_queue
#define rpriq priq<int, vector<int>, greater<int>>
#define deg_to_rad(deg) (((deg) / 360.0L) * 2.0L * PI)
#define rad_to_deg(rad) (((rad) / 2.0L / PI) * 360.0L)
#define Please return
#define AC 0
#define manhattan_dist(a, b, c, d)                                             \\
  (abs(a - c) + abs(b - d)) /*(a, b) から (c, d) のマンハッタン距離 */

using ll = long long;

constexpr int INF = 1073741823;
constexpr int MINF = -1073741823;
constexpr ll LINF = ll(4661686018427387903);
constexpr ll MOD = 1000000007;
const long double PI = acosl(-1.0L);

using namespace std;

void scans(string &str) {
  char c;
  str = "";
  scanf("%c", &c);
  if (c == '\\n')
    scanf("%c", &c);
  while (c != '\\n' && c != -1 && c != ' ') {
    str += c;
    scanf("%c", &c);
  }
}

void scanc(char &str) {
  char c;
  scanf("%c", &c);
  if (c == -1)
    return;
  while (c == '\\n') {
    scanf("%c", &c);
  }
  str = c;
}

double acot(double x) { return PI / 2 - atan(x); }

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll lcm(ll number1, ll number2) {
  return number1 / gcd(number1, number2) * number2;
}

ll LSB(ll n) { return (n & (-n)); }

/*-----------------------------------------ここからコード-----------------------------------------*/

// RMQ <O(n log n), O(1)>
template <typename T> struct sparsetable {

  vector<vector<T>> table;
  vector<int> logtable;
  vector<int> a;
  int n;

  // 渡す配列, サイズ
  sparsetable(const vector<T> a, int siz) : n(siz), a(a) {
    logtable.assign(n + 1, 0);
    for (int i = 2; i <= n; ++i)
      logtable[i] = logtable[i >> 1] + 1;
    table.assign(n, vector<T>(logtable[n] + 1, 0));
  }

  // リストバージョン
  sparsetable(initializer_list<T> init) {
    a = init[0];
    n = init[1];
    logtable.assign(n + 1, 0);
    for (int i = 2; i <= n; ++i)
      logtable[i] = logtable[i >> 1] + 1;
    table.assign(n, vector<T>(logtable[n] + 1, 0));
  }

  // 配列と大きさを渡して初期化
  void init(const vector<T> aa, int siz) {
    a = aa;
    n = siz;
    logtable.assign(n + 1, 0);
    for (int i = 2; i <= n; ++i)
      logtable[i] = logtable[i >> 1] + 1;
    table.assign(n, vector<T>(logtable[n] + 1, 0));
  }

  // 構築 O(n log n)
  void build() {
    for (int k = 0; (1 << k) <= n; ++k) {
      for (int i = 0; i + (1 << k) <= n; ++i) {
        if (k)
          table[i][k] =
              (a[table[i][k - 1]] < a[table[i + (1 << (k - 1))][k - 1]]
                   ? table[i][k - 1]
                   : table[i + (1 << (k - 1))][k - 1]);
        else
          table[i][k] = i;
      }
    }
  }

  //[l, r) の RMQ O(1)
  int query(int l, int r) {
    int k = logtable[r - l];
    return (a[table[l][k]] < a[table[r - (1 << k)][k]]
                ? table[l][k]
                : table[r - (1 << k)][k]);
  }
};

// depends on SparseTable

// euler tour を行う。O(n)
void eulertour(const int &now, const int &bef, int &cnt,
               const vector<vector<int>> &graph, const int &d, vector<int> &vs,
               vector<int> &depth, vector<int> &id) {
  depth.emplace_back(d);
  vs.emplace_back(now);
  id[now] = min(id[now], cnt);
  for (const auto &aa : graph[now]) {
    if (aa != bef) {
      ++cnt;
      eulertour(aa, now, cnt, graph, d + 1, vs, depth, id);
      ++cnt;
      depth.emplace_back(d);
      vs.emplace_back(now);
    }
  }
}

// LCA <O(n log n), O(1)>
struct LCA {

  vector<int> vs, depth, id, tmp = {0};
  vector<vector<int>> tree;
  sparsetable<int> table{tmp, 0};
  int n, root;

  // 木,　大きさ, 根で初期化
  LCA(vector<vector<int>> tree, int n, int root)
      : tree(tree), n(n), root(root) {
    id.assign(n, INF);
  }

  // 構築 O(n) + O(n log n)
  void build() {
    int cnt = 0, d = 0;
    eulertour(root, -1, cnt, tree, d, vs, depth, id);
    table.init(depth, depth.size());
    table.build();
  }

  // LCA である頂点を返す O(1)
  int query(int l, int r) {
    if (id[l] > id[r])
      swap(l, r);
    return vs[table.query(id[l], id[r] + 1)];
  }

  // 頂点 n の深さを返す O(1)
  int depthq(int n) { return depth[id[n]]; }
};

int main() {

  int n, x, y;
  scanf("%d%d%d", &n, &x, &y);
  --x;
  --y;
  int p = (x + y) / 2;
  vector<vector<int>> a(n), b(n);
  rep(i, n - 1) {
    if (p != i) {
      a[i].pb(i + 1);
      a[i + 1].pb(i);
    }
    b[i].pb(i + 1);
    b[i + 1].pb(i);
  }
  a[x].pb(y);
  a[y].pb(x);

  LCA lca1(a, n, 0);
  LCA lca2(b, n, 0);
  lca1.build();
  lca2.build();
  vector<int> ans(n);
  int dist1, dist2;
  rep(i, n) {
    for (int j = i + 1; j < n; ++j) {
      dist1 =
          lca1.depthq(i) + lca1.depthq(j) - 2 * lca1.depthq(lca1.query(i, j));
      dist2 =
          lca2.depthq(i) + lca2.depthq(j) - 2 * lca2.depthq(lca2.query(i, j));
      ++ans[min(dist1, dist2) - 1];
    }
  }
  rep(i, n - 1) printf("%d\\n", ans[i]);

  Please AC;
}

Error: WA

Fixed submission:

/*
このコード、と～おれ!
Be accepted!
∧＿∧　
（｡･ω･｡)つ━☆・*。
⊂　　 ノ 　　　・゜+.
　しーＪ　　　°。+ *´¨)
 　　　　　　　　　.· ´¸.·*´¨) ¸.·*¨)
                  　　　　　　　　　　(¸.·´ (¸.·'* ☆
*/

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
/*多倍長整数/cpp_intで宣言
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
*/

#pragma gcc target("avx2")
#pragma gcc optimization("o3")
#pragma gcc optimization("unroll-loops")
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define rep2(i, n) for (int i = 2; i < (n); ++i)
#define repr(i, n) for (int i = n; i >= 0; --i)
#define reprm(i, n) for (int i = n - 1; i >= 0; --i)
#define printynl(a) printf(a ? "yes\\n" : "no\\n")
#define printyn(a) printf(a ? "Yes\\n" : "No\\n")
#define printYN(a) printf(a ? "YES\\n" : "NO\\n")
#define printim(a) printf(a ? "possible\\n" : "imposible\\n")
#define printdb(a) printf("%.50lf\\n", a)    // 少数出力
#define printLdb(a) printf("%.50Lf\\n", a)   // 少数出力
#define printdbd(a) printf("%.16lf\\n", a)   // 少数出力(桁少なめ)
#define prints(s) printf("%s\\n", s.c_str()) // string出力
#define all(x) (x).begin(), (x).end()
#define allsum(a, b, c) ((a + b) * c / 2.0) // 等差数列の和、初項,末項,項数
#define pb push_back
#define priq priority_queue
#define rpriq priq<int, vector<int>, greater<int>>
#define deg_to_rad(deg) (((deg) / 360.0L) * 2.0L * PI)
#define rad_to_deg(rad) (((rad) / 2.0L / PI) * 360.0L)
#define Please return
#define AC 0
#define manhattan_dist(a, b, c, d)                                             \\
  (abs(a - c) + abs(b - d)) /*(a, b) から (c, d) のマンハッタン距離 */

using ll = long long;

constexpr int INF = 1073741823;
constexpr int MINF = -1073741823;
constexpr ll LINF = ll(4661686018427387903);
constexpr ll MOD = 1000000007;
const long double PI = acosl(-1.0L);

using namespace std;

void scans(string &str) {
  char c;
  str = "";
  scanf("%c", &c);
  if (c == '\\n')
    scanf("%c", &c);
  while (c != '\\n' && c != -1 && c != ' ') {
    str += c;
    scanf("%c", &c);
  }
}

void scanc(char &str) {
  char c;
  scanf("%c", &c);
  if (c == -1)
    return;
  while (c == '\\n') {
    scanf("%c", &c);
  }
  str = c;
}

double acot(double x) { return PI / 2 - atan(x); }

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll lcm(ll number1, ll number2) {
  return number1 / gcd(number1, number2) * number2;
}

ll LSB(ll n) { return (n & (-n)); }

/*-----------------------------------------ここからコード-----------------------------------------*/

int graph[200][200];

// ワーシャルフロイド
void WarshallFloyd(int n) {
  rep(i, n) {     // 経由する頂点
    rep(j, n) {   // 始点
      rep(k, n) { // 終点
        graph[j][k] = min(graph[j][k], graph[j][i] + graph[i][k]);
      }
    }
  }
}

int main() {

  int n, x, y;
  scanf("%d%d%d", &n, &x, &y);
  --x;
  --y;
  rep(i, n) {
    for (int j = i; j < n; ++j) {
      if (i == j)
        graph[i][j] = 0;
      else if (i + 1 == j) {
        graph[i][j] = 1;
        graph[j][i] = 1;
      } else {
        graph[i][j] = INF;
      }
    }
  }
  graph[x][y] = 1;
  graph[y][x] = 1;
  WarshallFloyd(n);
  int ans[n];
  rep(i, n) for (int j = i + 1; j < n; ++j) { ++ans[graph[i][j] - 1]; }
  rep(i, n - 1) printf("%d\\n", ans[i]);
  ;

  Please AC;
}