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

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

#define for_(i, a, b) for (int i = a; i < b; ++i)

typedef long long lint;

const lint MOD = (lint)1e9 + 7;

lint gcd(lint _a, lint _b) { return _b != 0 ? gcd(_b, _a % _b) : _a; }

lint lcm(lint _a, lint _b) { return _a / gcd(_a, _b) * _b; }

typedef pair<lint, lint> Val;

class SegTree {
private:
  int t_size;
  vector<Val> data;

  int right_t(int k) { return 2 * k + 2; }

  int left_t(int k) { return 2 * k + 1; }

public:
  SegTree(int size_) {
    t_size = 1;
    while (t_size < size_)
      t_size *= 2;
    data.assign(2 * t_size - 1, Val(1, 0));
  }

  Val calculation(Val v1, Val v2) {
    lint vf1 = v1.first, vf2 = v2.first;
    lint lcm_ = lcm(vf1, vf2);
    lint mul1 = lcm_ / vf1 % MOD, mul2 = lcm_ / vf2 % MOD;
    return Val(lcm_, (mul1 * v1.second + mul2 * v2.second) % MOD);
  }

  void update(int k, Val v) {
    k += t_size - 1;
    data[k] = v;

    while (k > 0) {
      k = (k - 1) / 2;
      data[k] = calculation(data[left_t(k)], data[right_t(k)]);
    }
  }

  Val query(int a, int b) { return query(a, b, 0, 0, t_size); }

  Val query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return Val(1, 0);
    if (a <= l && r <= b)
      return data[k];
    return calculation(query(a, b, left_t(k), l, (l + r) / 2),
                       query(a, b, right_t(k), (l + r) / 2, r));
  }
};

int main() {
  int N, Q;
  cin >> N >> Q;

  vector<int> p(N), x(N);

  for_(i, 0, N) {
    cin >> p[i];
    --p[i];
    x[i] = i;
  }

  SegTree segt(N);

  vector<int> hit(N, 0), sum(N, 0);

  for_(i, 1, 41) {
    vector<int> y(N);
    for_(j, 0, N) y[j] = p[x[j]];

    for_(j, 0, N) {
      x[j] = y[j];
      sum[j] += x[j] + 1;

      if (x[j] == j && hit[j] == 0) {
        segt.update(j, Val(i, sum[j]));
        hit[j] = 1;
      }
    }
  }

  for_(i, 0, Q) {
    int l, r;
    cin >> l >> r;

    Val ans = segt.query(l - 1, r);

    cout << ans.second << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

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

#define for_(i, a, b) for (int i = a; i < b; ++i)

typedef long long lint;

const lint MOD = (lint)1e9 + 7;

lint gcd(lint _a, lint _b) { return _b != 0 ? gcd(_b, _a % _b) : _a; }

lint lcm(lint _a, lint _b) { return _a * _b / gcd(_a, _b); }

typedef pair<lint, lint> Val;

class SegTree {
private:
  int t_size;
  vector<Val> data;

  int right_t(int k) { return 2 * k + 2; }

  int left_t(int k) { return 2 * k + 1; }

public:
  SegTree(int size_) {
    t_size = 1;
    while (t_size < size_)
      t_size *= 2;
    data.assign(2 * t_size - 1, Val(1, 0));
  }

  Val calculation(Val v1, Val v2) {
    lint vf1 = v1.first, vf2 = v2.first;
    lint lcm_ = lcm(vf1, vf2);
    return Val(lcm_, (lcm_ / vf1 * v1.second + lcm_ / vf2 * v2.second) % MOD);
  }

  void update(int k, Val v) {
    k += t_size - 1;
    data[k] = v;

    while (k > 0) {
      k = (k - 1) / 2;
      data[k] = calculation(data[left_t(k)], data[right_t(k)]);
    }
  }

  Val query(int a, int b) { return query(a, b, 0, 0, t_size); }

  Val query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return Val(1, 0);
    if (a <= l && r <= b)
      return data[k];
    return calculation(query(a, b, left_t(k), l, (l + r) / 2),
                       query(a, b, right_t(k), (l + r) / 2, r));
  }
};

int main() {
  int N, Q;
  cin >> N >> Q;

  vector<int> p(N), x(N);

  for_(i, 0, N) {
    cin >> p[i];
    --p[i];
    x[i] = i;
  }

  SegTree segt(N + 5);

  vector<int> hit(N, 0), sum(N, 0);

  for_(i, 1, 41) {
    vector<int> y(N);
    for_(j, 0, N) y[j] = p[x[j]];
    x = y;

    for_(j, 0, N) {
      sum[j] += x[j] + 1;
      if (x[j] == j && hit[j] == 0) {
        segt.update(j, Val(i, sum[j]));
        hit[j] = 1;
      }
    }
  }

  for_(i, 0, Q) {
    int l, r;
    cin >> l >> r;

    Val ans = segt.query(l - 1, r);

    cout << ans.second << endl;
  }

  return 0;
}