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

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

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1e9;
const int64_t inf64 = 1e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

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

int64_t lcm(int64_t a, int64_t b) { return a / gcd(a, b) * b; }

template <class T> class segtree {
public:
  int n, size_;
  vector<T> dat;
  function<T(T, T)> fun_;
  T id_;
  segtree() = default;
  segtree(int size, function<T(T, T)> fun, T id, T initial_value) {
    init(size, fun, id, initial_value);
  }
  void init(int size, function<T(T, T)> fun, T id, T initial_value) {
    size_ = size;
    fun_ = fun;
    id_ = id;
    n = 1;
    while (n < size)
      n *= 2;
    dat.assign(2 * n - 1, id);
    for (int i = 0; i < size; ++i)
      update(i, initial_value);
  }
  int size() const { return size_; }
  void update(int k, T a) {
    k += n - 1; // leaf
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = fun_(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  T at(int index) { return dat[index + n - 1]; }
  void add(int k, T a) { update(k, at(k) + a); }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a or b <= l)
      return id_;
    if (a <= l and r <= b)
      return dat[k];
    int m = (l + r) / 2;
    return fun_(query(a, b, k * 2 + 1, l, m), query(a, b, k * 2 + 2, m, r));
  }
};

void solve() {
  int n, q;
  cin >> n >> q;
  vector<int> p(n);
  rep(i, 0, n) cin >> p[i];

  int64_t mod = 1e9 + 7;
  vector<vector<int64_t>> period(n), cumsum(41, vector<int64_t>(n));
  vector<int64_t> sum(n);
  segtree<int64_t> seg(n, lcm, 1, 1);
  rep(i, 0, n) {
    int z = i + 1;
    for (;;) {
      z = p[z - 1];
      period[i].push_back(z);
      sum[i] += z;
      if (z == i + 1)
        break;
    }
    cumsum[period[i].size()][i] = sum[i];
    rep(j, 0, 41) cumsum[j][i] =
        (cumsum[j][i] + (i > 0 ? cumsum[j][i - 1] : 0)) % mod;
    seg.update(i, period[i].size());
  }
  rep(i, 0, q) {
    int l, r;
    cin >> l >> r;
    --l;
    --r;
    int64_t lcm_ = seg.query(l, r + 1), ans = 0;
    rep(j, 1, 41) ans =
        (ans +
         lcm_ / j % mod * (cumsum[j][r] - (l > 0 ? cumsum[j][l - 1] : 0)) %
             mod +
         mod) %
        mod;
    cout << ans << endl;
  }
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  solve();
  return 0;
}

Error: TLE

Fixed submission:

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

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1e9;
const int64_t inf64 = 1e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

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

int64_t lcm(int64_t a, int64_t b) { return a / gcd(a, b) * b; }

template <class T> class segtree {
public:
  int n, size_;
  vector<T> dat;
  function<T(T, T)> fun_;
  T id_;
  segtree() = default;
  segtree(int size, function<T(T, T)> fun, T id, T initial_value) {
    init(size, fun, id, initial_value);
  }
  void init(int size, function<T(T, T)> fun, T id, T initial_value) {
    size_ = size;
    fun_ = fun;
    id_ = id;
    n = 1;
    while (n < size)
      n *= 2;
    dat.assign(2 * n - 1, id);
    for (int i = 0; i < size; ++i)
      update(i, initial_value);
  }
  int size() const { return size_; }
  void update(int k, T a) {
    k += n - 1; // leaf
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = fun_(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }
  T at(int index) { return dat[index + n - 1]; }
  void add(int k, T a) { update(k, at(k) + a); }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a or b <= l)
      return id_;
    if (a <= l and r <= b)
      return dat[k];
    int m = (l + r) / 2;
    return fun_(query(a, b, k * 2 + 1, l, m), query(a, b, k * 2 + 2, m, r));
  }
};

void solve() {
  int n, q;
  cin >> n >> q;
  vector<int> p(n);
  rep(i, 0, n) cin >> p[i];

  vector<vector<int64_t>> period(n);
  vector<int64_t> sum(n);
  segtree<int64_t> seg(n, lcm, 1, 1);
  rep(i, 0, n) {
    int z = i + 1;
    for (;;) {
      z = p[z - 1];
      period[i].push_back(z);
      sum[i] += z;
      if (z == i + 1)
        break;
    }
    seg.update(i, period[i].size());
  }

  vector<int> ls(q), rs(q);
  // vector<int64_t> lcms;
  rep(i, 0, q) {
    cin >> ls[i] >> rs[i];
    --ls[i];
    --rs[i];
    // lcms.push_back(seg.query(ls[i],rs[i]+1));
  }
  // sort(lcms.begin(),lcms.end());
  // lcms.erase(unique(lcms.begin(),lcms.end()),lcms.end());

  int64_t mod = 1e9 + 7;
  rep(i, 0, q) {
    int l = ls[i], r = rs[i];
    print("AAAAAAAAAAAAAAA");
    int64_t lcm_ = seg.query(l, r + 1), ans = 0;
    print("BBBBBBBBBBBBBBB");
    rep(j, l, r + 1) {
      ans = (ans + lcm_ / period[j].size() % mod * sum[j] % mod) % mod;
      rep(k, 0, lcm_ % period[j].size()) ans = (ans + period[j][k]) % mod;
    }
    cout << ans << endl;
  }
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  solve();
  return 0;
}