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

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

typedef long long lli;
const lli mod = 1000000007LL;

lli lcm(lli a, lli b) { return a / __gcd(a, b) * b; }

lli mod_pow(lli x, lli n) {
  if (n == 0)
    return 1;
  lli p = mod_pow(x, n / 2);
  if (n & 1)
    return p * p % mod * x % mod;
  else
    return p * p % mod;
}

typedef lli elm;
const elm INF = 1LL << 60LL;

class RMQ {
private:
  int n;
  vector<elm> dat;

public:
  RMQ(int _n) {
    n = 1;
    while (n < _n)
      n *= 2;
    dat = vector<elm>(2 * n - 1, 0);
  }

  void update(int k, elm a) {
    k += n - 1;
    a %= mod;
    elm d = ((a - dat[k]) % mod + mod) % mod;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      (dat[k] += d) %= mod;
    }
  }

  elm query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return dat[k];
    else {
      elm v1 = query(a, b, k * 2 + 1, l, (l + r) / 2);
      elm v2 = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return (v1 + v2) % mod;
    }
  }
};

class RMQ2 {
private:
  int n;
  vector<elm> dat;

public:
  RMQ2(int _n) {
    n = 1;
    while (n < _n)
      n *= 2;
    dat = vector<elm>(2 * n - 1, 1);
  }

  void update(int k, elm a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = lcm(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  elm query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return 1;
    if (a <= l && r <= b)
      return dat[k];
    else {
      elm v1 = query(a, b, k * 2 + 1, l, (l + r) / 2);
      elm v2 = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return lcm(v1, v2);
    }
  }
};

int main() {
  vector<lli> inv(41);
  for (lli i = 1; i <= 40; ++i) {
    inv[i] = mod_pow(i, mod - 2);
  }

  lli N, Q;
  cin >> N >> Q;
  vector<lli> p(N + 1);
  for (lli i = 1; i <= N; ++i) {
    cin >> p[i];
  }

  vector<lli> vis(N + 1);
  RMQ rmq(N + 1);
  RMQ2 rmq2(N + 1);
  for (lli i = 1; i <= N; ++i) {
    if (vis[i])
      continue;
    lli k = i, s = 0, t = 0;
    do {
      k = p[k];
      vis[k] = true;
      s += k;
      ++t;
    } while (k != i);
    do {
      k = p[k];
      rmq.update(k, s * inv[t] % mod);
      rmq2.update(k, t);
    } while (k != i);
  }

  while (Q--) {
    lli l, r;
    cin >> l >> r;
    cout << (rmq.query(l, r + 1) % mod) * (rmq2.query(l, r + 1) % mod) % mod
         << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

typedef long long lli;
const lli mod = 1000000007LL;

lli lcm(lli a, lli b) { return a * b / __gcd(a, b); }

int main() {
  lli N, Q;
  cin >> N >> Q;
  vector<lli> p(N + 1);
  for (lli i = 1; i <= N; ++i) {
    cin >> p[i];
  }
  vector<lli> vis(N + 1, -1);
  int n = 0;
  vector<lli> S(N + 1), T(N + 1), U(N + 1);
  for (lli tc = 0; tc < Q; ++tc) {
    lli l, r;
    cin >> l >> r;
    n = 0;
    for (lli i = l; i <= r; ++i) {
      if (vis[i] == tc)
        continue;
      lli k = i, s = 0, t = 0, u = 0;
      do {
        k = p[k];
        vis[k] = tc;
        s += k;
        ++t;
        if (l <= k && k <= r)
          ++u;
      } while (k != i);
      S[n] = s;
      T[n] = t;
      U[n] = u;
      ++n;
    }
    lli L = 1;
    for (lli i = 0; i < n; ++i) {
      L = lcm(L, T[i]);
    }
    lli res = 0;
    for (lli i = 0; i < n; ++i) {
      (res += L / T[i] * U[i] * S[i]) %= mod;
    }
    cout << res << endl;
  }
  return 0;
}