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

#include <algorithm>
#include <assert.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
#define loop(i, a, b) for (int i = a; i < b; i++)
#define rep(i, a) loop(i, 0, a)
#define pb push_back
#define all(in) in.begin(), in.end()
#define shosu(x) fixed << setprecision(x)
using namespace std;
// kaewasuretyuui
typedef long long ll;
// #define int ll
typedef ll Def;
typedef pair<Def, Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def, pii> pip;
typedef vector<pip> vip;
// #define mt make_tuple
// typedef tuple<pii,int,int> tp;
// typedef vector<tp> vt;
template <typename A, typename B> bool cmin(A &a, const B &b) {
  return a > b ? (a = b, true) : false;
}
template <typename A, typename B> bool cmax(A &a, const B &b) {
  return a < b ? (a = b, true) : false;
}
// template<class C>constexpr int size(const C &c){return (int)c.size();}
// template<class T,size_t N> constexpr int size(const T
// (&xs)[N])noexcept{return (int)N;}
const double PI = acos(-1);
const double EPS = 1e-7;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9;
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
ll gcd(ll a, ll b) { return (b == 0 ? a : gcd(b, a % b)); }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
// nCr mod m
#define MOD 1000000007
#define M 1000000
vector<ll> fact;
bool h = false;
void init() {
  h = true;
  fact = vector<ll>(M);
  fact[0] = fact[1] = 1;
  loop(i, 2, M) fact[i] = fact[i - 1] * i % MOD;
}
// a^b mod MOD
ll powmod(ll a, ll b, ll m) {
  ll out = 1;
  ll p = a % m;
  while (b) {
    if (b & 1)
      out = out * p % m;
    p = p * p % m;
    b >>= 1;
  }
  return out;
}
typedef pii SegT;
const SegT defvalue = {1, 0};
class SegTree {
private:
  vector<SegT> val;
  int n;
  SegT combine(SegT a, SegT b) {
    ll fi = lcm(a.first, b.first);
    ll se = fi % MOD * powmod(a.first, MOD - 2, MOD) % MOD * a.second % MOD;
    se += fi % MOD * powmod(b.first, MOD - 2, MOD) % MOD * b.second % MOD;
    return {fi, se % MOD};
  }

public:
  SegTree(int size) {
    n = 1;
    while (n < size)
      n <<= 1;
    val = vector<SegT>(2 * n, defvalue);
  }
  SegTree(const vector<SegT> &in) {
    n = 1;
    while (n < in.size())
      n <<= 1;
    val = vector<SegT>(2 * n, defvalue);
    for (int i = n - 1 + in.size() - 1; i >= 0; i--) {
      if (n - 1 <= i)
        val[i] = in[i - (n - 1)];
      else
        val[i] = combine(val[i * 2 + 1], val[i * 2 + 2]);
    }
  }
  void update(int i, SegT a) {
    i += n - 1;
    val[i] = a;
    while (i > 0) {
      i = (i - 1) / 2;
      val[i] = combine(val[i * 2 + 1], val[i * 2 + 2]);
    }
  }
  SegT query(int a, int b, int k = 0, int l = 0, int r = -1) { //[a,b)
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return defvalue;
    if (a <= l && r <= b)
      return val[k];
    else
      return combine(query(a, b, k * 2 + 1, l, (l + r) / 2),
                     query(a, b, k * 2 + 2, (l + r) / 2, r));
  }
  void tmp() {
    rep(i, val.size()) cout << " " << val[i].first << " " << val[i].second
                            << endl;
  }
};
int main() {
  ll n, q;
  cin >> n >> q;
  vi in(n);
  rep(i, n) cin >> in[i];
  SegTree st(n);
  rep(i, n) {
    ll sum = 0;
    ll t = i;
    int co = 0;
    do {
      co++;
      (sum += t + 1) %= MOD;
      t = in[t] - 1;
    } while (t != i);
    st.update(i, {co, sum});
  }
  while (q--) {
    ll l, r;
    cin >> l >> r;
    l--;
    cout << st.query(l, r).second << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <typeinfo>
#include <utility>
#include <vector>
#define loop(i, a, b) for (int i = a; i < b; i++)
#define rep(i, a) loop(i, 0, a)
#define pb push_back
#define all(in) in.begin(), in.end()
#define shosu(x) fixed << setprecision(x)
using namespace std;
// kaewasuretyuui
typedef long long ll;
// #define int ll
typedef ll Def;
typedef pair<Def, Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def, pii> pip;
typedef vector<pip> vip;
// #define mt make_tuple
// typedef tuple<pii,int,int> tp;
// typedef vector<tp> vt;
template <typename A, typename B> bool cmin(A &a, const B &b) {
  return a > b ? (a = b, true) : false;
}
template <typename A, typename B> bool cmax(A &a, const B &b) {
  return a < b ? (a = b, true) : false;
}
// template<class C>constexpr int size(const C &c){return (int)c.size();}
// template<class T,size_t N> constexpr int size(const T
// (&xs)[N])noexcept{return (int)N;}
const double PI = acos(-1);
const double EPS = 1e-7;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9;
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
typedef ll SegT;
const SegT defvalue = 0;
class SegTree {
private:
  vector<SegT> val;
  int n;
  SegT combine(SegT a, SegT b) { return max(a, b); }

public:
  SegTree(int size) {
    n = 1;
    while (n < size)
      n <<= 1;
    val = vector<SegT>(2 * n, defvalue);
  }
  SegTree(const vector<SegT> &in) {
    n = 1;
    while (n < in.size())
      n <<= 1;
    val = vector<SegT>(2 * n, defvalue);
    for (int i = n - 1 + in.size() - 1; i >= 0; i--) {
      if (n - 1 <= i)
        val[i] = in[i - (n - 1)];
      else
        val[i] = combine(val[i * 2 + 1], val[i * 2 + 2]);
    }
  }
  void update(int i, SegT a) {
    i += n - 1;
    val[i] = a;
    while (i > 0) {
      i = (i - 1) / 2;
      val[i] = combine(val[i * 2 + 1], val[i * 2 + 2]);
    }
  }
  SegT query(int a, int b, int k = 0, int l = 0, int r = -1) { //[a,b)
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return defvalue;
    if (a <= l && r <= b)
      return val[k];
    else
      return combine(query(a, b, k * 2 + 1, l, (l + r) / 2),
                     query(a, b, k * 2 + 2, (l + r) / 2, r));
  }
  void tmp() {
    rep(i, val.size()) cout << " " << val[i];
    cout << endl;
  }
};
// nCr mod m
#define MOD 1000000007
#define M 1000000
vector<ll> fact;
bool h = false;
void init() {
  h = true;
  fact = vector<ll>(M);
  fact[0] = fact[1] = 1;
  loop(i, 2, M) fact[i] = fact[i - 1] * i % MOD;
}
// a^b mod MOD
ll powmod(ll a, ll b, ll m) {
  ll out = 1;
  ll p = a % m;
  while (b) {
    if (b & 1)
      out = out * p % m;
    p = p * p % m;
    b >>= 1;
  }
  return out;
}
int main() {
  ll n, q;
  cin >> n >> q;
  vi in(n);
  rep(i, n) cin >> in[i];
  vp sum(n);
  rep(i, n) {
    ll t = i;
    int co = 0;
    do {
      co++;
      sum[i].first += t + 1;
      sum[i].first %= MOD;
      t = in[t] - 1;
    } while (t != i);
    sum[i].second = co;
  }
  //	rep(i,n)cout<<sum[i].first<<" "<<sum[i].second<<endl;
  vector<SegTree> dp(40, SegTree(n));
  rep(i, n) {
    ll t = sum[i].second;
    loop(j, 2, 40) {
      int co = 0;
      while (t % j == 0) {
        co++;
        t /= j;
      }
      dp[j].update(i, co);
    }
  }
  vi pm(41);
  loop(i, 1, 41) pm[i] = powmod(i, MOD - 2, MOD);
  while (q--) {
    ll l, r;
    cin >> l >> r;
    l--;
    ll t = 1;
    rep(i, 40) {
      ll co = dp[i].query(l, r);
      //			cout<<" "<<i<<" "<<co<<endl;
      if (co != inf)
        rep(j, co) t *= i;
    }
    ll out = 0;
    loop(i, l, r)(out += t % MOD * pm[sum[i].second] % MOD * sum[i].first %
                         MOD) %= MOD;
    cout << out << endl;
  }
}