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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
#define MOD 1000000007ll
#define INF 1000000000ll
#define EPS 1e-7
#define FOR(i, n, m) for (ll i = n; i < (ll)m; i++)
#define REP(i, n) FOR(i, 0, n)
#define DUMP(a)                                                                \\
  REP(d, a.size()) {                                                           \\
    cout << a[d];                                                              \\
    if (d != a.size() - 1)                                                     \\
      cout << " ";                                                             \\
    else                                                                       \\
      cout << endl;                                                            \\
  }
#define ALL(v) v.begin(), v.end()
#define UNIQUE(v)                                                              \\
  sort(v.begin(), v.end());                                                    \\
  v.erase(unique(v.begin(), v.end()), v.end());
#define pb push_back

ll _pow(ll a, ll n) {
  if (n == 0)
    return 1;
  else {
    ll res = 1;
    ll buf = a;
    while (n > 0) {
      if (n % 2 == 1) {
        res *= buf;
        res %= MOD;
      }
      buf *= buf;
      buf %= MOD;
      n /= 2;
    }
    return res;
  }
}

class segtree {
public:
  segtree(int n) {
    _n = 1;
    while (_n < n)
      _n *= 2;
    _dat.resize(2 * _n - 1);
    _dat2.resize(2 * _n - 1);
    for (int i = 0; i < 2 * _n - 1; ++i) {
      _dat[i] = vector<char>(200);
      _dat2[i] = 0;
    }
  }
  int size() { return _n; }
  void update(int k, long long a) {
    k += _n - 1;
    _dat[k][a]++;
    while (k > 0) {
      k = (k - 1) / 2;
      REP(i, 200) _dat[k][i] = max(_dat[k * 2 + 1][i], _dat[k * 2 + 2][i]);
    }
  }
  void update2(int k, long long a) {
    k += _n - 1;
    _dat2[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      _dat2[k] = (_dat2[k * 2 + 1] + _dat2[k * 2 + 2]) % MOD;
    }
  }
  vector<char> 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 vector<char>(200, 0);
    if (a <= l && r <= b)
      return _dat[k];
    else {
      vector<char> vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      vector<char> vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      vector<char> ret(200, 0);
      REP(i, 200) ret[i] = max(vl[i], vr[i]);
      return ret;
    }
  }
  ll query2(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 _dat2[k] % MOD;
    else {
      ll vl = query2(a, b, k * 2 + 1, l, (l + r) / 2);
      ll vr = query2(a, b, k * 2 + 2, (l + r) / 2, r);
      return (vl + vr) % MOD;
    }
  }

private:
  int _n;
  vector<vector<char>> _dat;
  vector<ll> _dat2;
};

struct dat {
  ll sum;
  ll lgt;
};

vector<int> p;
vector<dat> info;
ll c = 0;
map<int, int> prim_dict;
vector<int> prim;

dat dfs(ll pos, vector<bool> &used, ll sum, ll cnt) {
  sum += pos + 1;
  cnt++;
  used[pos] = true;
  if (used[p[pos]])
    return info[pos] = dat{sum, cnt};
  else
    return info[pos] = dfs(p[pos], used, sum, cnt);
}

void prifact(ll num, vector<ll> &v) {
  while (num > 1) {
    bool upd = false;
    for (ll i = 2; i * i <= num; i++) {
      if (num % i == 0) {
        upd = true;
        v.pb(i);
        if (prim_dict.count(i) == 0) {
          prim_dict[i] = c;
          c++;
          prim.pb(i);
        }
        num /= i;
        break;
      }
    }
    if (!upd)
      break;
  }
  if (num != 1) {
    if (prim_dict.count(num) == 0) {
      prim_dict[num] = c;
      c++;
      prim.pb(num);
    }
    v.pb(num);
  }
  return;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n, q;
  cin >> n >> q;
  p.assign(n, 0);
  info.assign(n, dat{0, 0});
  REP(i, n) cin >> p[i];
  REP(i, n) p[i]--;
  segtree seg(n);
  vector<bool> used(n, false);
  REP(i, n) if (!used[i]) dfs(i, used, 0, 0);
  map<ll, vector<ll>> prifact_dict;
  REP(i, n) if (!prifact_dict.count(info[i].lgt)) {
    vector<ll> v;
    prifact(info[i].lgt, v);
    prifact_dict[info[i].lgt] = v;
  }
  REP(i, n) {
    vector<ll> v = prifact_dict[info[i].lgt];
    REP(j, (ll)v.size()) seg.update(i, prim_dict[v[j]]);
  }
  REP(i, n)
  seg.update2(i, ((info[i].sum % MOD) * _pow(info[i].lgt, MOD - 2)) % MOD);
  REP(query, q) {
    ll l, r;
    cin >> l >> r;
    l--;
    r--;
    vector<char> v = seg.query(l, r + 1);
    ll mult = 1;
    REP(i, c) {
      mult *= _pow(prim[i], v[i]);
      mult %= MOD;
    }
    cout << ((seg.query2(l, r + 1) * mult) % MOD + MOD) % MOD << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
#define MOD 1000000007ll
#define INF 1000000000ll
#define EPS 1e-7
#define FOR(i, n, m) for (ll i = n; i < (ll)m; i++)
#define REP(i, n) FOR(i, 0, n)
#define DUMP(a)                                                                \\
  REP(d, a.size()) {                                                           \\
    cout << a[d];                                                              \\
    if (d != a.size() - 1)                                                     \\
      cout << " ";                                                             \\
    else                                                                       \\
      cout << endl;                                                            \\
  }
#define ALL(v) v.begin(), v.end()
#define UNIQUE(v)                                                              \\
  sort(v.begin(), v.end());                                                    \\
  v.erase(unique(v.begin(), v.end()), v.end());
#define pb push_back

ll _pow(ll a, ll n) {
  if (n == 0)
    return 1;
  else {
    ll res = 1;
    ll buf = a;
    while (n > 0) {
      if (n % 2 == 1) {
        res *= buf;
        res %= MOD;
      }
      buf *= buf;
      buf %= MOD;
      n /= 2;
    }
    return res;
  }
}

class segtree {
public:
  segtree(int n) {
    _n = 1;
    while (_n < n)
      _n *= 2;
    _dat.resize(2 * _n - 1);
    _dat2.resize(2 * _n - 1);
    for (int i = 0; i < 2 * _n - 1; ++i) {
      _dat[i] = vector<char>(350);
      _dat2[i] = 0;
    }
  }
  int size() { return _n; }
  void update(int k, long long a) {
    k += _n - 1;
    _dat[k][a]++;
    while (k > 0) {
      k = (k - 1) / 2;
      REP(i, 350) _dat[k][i] = max(_dat[k * 2 + 1][i], _dat[k * 2 + 2][i]);
    }
  }
  void update2(int k, long long a) {
    k += _n - 1;
    _dat2[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      _dat2[k] = (_dat2[k * 2 + 1] + _dat2[k * 2 + 2]) % MOD;
    }
  }
  vector<char> 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 vector<char>(350, 0);
    if (a <= l && r <= b)
      return _dat[k];
    else {
      vector<char> vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      vector<char> vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      vector<char> ret(350, 0);
      REP(i, 350) ret[i] = max(vl[i], vr[i]);
      return ret;
    }
  }
  ll query2(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 _dat2[k] % MOD;
    else {
      ll vl = query2(a, b, k * 2 + 1, l, (l + r) / 2);
      ll vr = query2(a, b, k * 2 + 2, (l + r) / 2, r);
      return (vl + vr) % MOD;
    }
  }

private:
  int _n;
  vector<vector<char>> _dat;
  vector<ll> _dat2;
};

struct dat {
  ll sum;
  ll lgt;
};

vector<int> p;
vector<dat> info;
ll c = 0;
map<int, int> prim_dict;
vector<int> prim;

dat dfs(ll pos, vector<bool> &used, ll sum, ll cnt) {
  sum += pos + 1;
  cnt++;
  used[pos] = true;
  if (used[p[pos]])
    return info[pos] = dat{sum, cnt};
  else
    return info[pos] = dfs(p[pos], used, sum, cnt);
}

void prifact(ll num, vector<ll> &v) {
  while (num > 1) {
    bool upd = false;
    for (ll i = 2; i * i <= num; i++) {
      if (num % i == 0) {
        upd = true;
        v.pb(i);
        if (prim_dict.count(i) == 0) {
          prim_dict[i] = c;
          c++;
          prim.pb(i);
        }
        num /= i;
        break;
      }
    }
    if (!upd)
      break;
  }
  if (num != 1) {
    if (prim_dict.count(num) == 0) {
      prim_dict[num] = c;
      c++;
      prim.pb(num);
    }
    v.pb(num);
  }
  return;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n, q;
  cin >> n >> q;
  p.assign(n, 0);
  info.assign(n, dat{0, 0});
  REP(i, n) cin >> p[i];
  REP(i, n) p[i]--;
  segtree seg(n);
  vector<bool> used(n, false);
  REP(i, n) if (!used[i]) dfs(i, used, 0, 0);
  map<ll, vector<ll>> prifact_dict;
  REP(i, n) if (!prifact_dict.count(info[i].lgt)) {
    vector<ll> v;
    prifact(info[i].lgt, v);
    prifact_dict[info[i].lgt] = v;
  }
  REP(i, n) {
    vector<ll> v = prifact_dict[info[i].lgt];
    REP(j, (ll)v.size()) seg.update(i, prim_dict[v[j]]);
  }
  REP(i, n)
  seg.update2(i, ((info[i].sum % MOD) * _pow(info[i].lgt, MOD - 2)) % MOD);
  REP(query, q) {
    ll l, r;
    cin >> l >> r;
    l--;
    r--;
    vector<char> v = seg.query(l, r + 1);
    ll mult = 1;
    REP(i, c) {
      mult *= _pow(prim[i], v[i]);
      mult %= MOD;
    }
    cout << ((seg.query2(l, r + 1) * mult) % MOD + MOD) % MOD << endl;
  }
}