Problem:
LCM of GCDs
You are given a sequence of positive integers, followed by a number of instructions specifying
updates to be made and queries to be answered on the sequence. Updates and queries are given
in an arbitrary order.
Each of the updates replaces a single item in the sequence with a given value. Updates are
accumulated: all the following instructions are on the sequence after the specified replacement.
Each of the queries specifies a subsequence of the (possibly updated) sequence and the number
of items to exclude from that subsequence. One or more sets of integers will result depending
on which of the items are excluded. Each of such sets has the greatest common divisor (GCD)
of its members. The answer to the query is the least common multiple (LCM) of the GCDs of
all these sets.
Figure H.1. Answering the last query "Q 2 5 2" of the Sample Input 1
Input
The input consists of a single test case of the following format.
$n$ $m$
$a_1$ ... $a_n$
$c_1$
...
$c_m$
The first line has two integers, $n$ and $m$. $n$ ($1 \leq n \leq 10^5$) is the length of the integer sequence, and $m$ ($1 \leq m \leq 10^5$) is the number of instructions. The original integer sequence $a_1, ...,  a_n$ is given in the second line. $1 \leq a_i \leq 10^6$ holds for $i = 1, ..., n$. Each of the following $m$ lines has either an update instruction starting with a letter
U
, or a query instruction starting with a letter
Q
.
An update instruction has the following format.
U $j$ $x$
The instruction tells to replace the $j$-th item of the sequence with an integer $x$. $1 \leq j \leq n$ and $1 \leq x \leq 10^6$ hold. Updates are accumulated: all the instructions below are on the sequence after the updates.
A query instruction has the following format.
Q $l$ $r$ $k$
Here, $l$ and $r$ specify the start and the end positions of a subsequence, and $k$ is the number of items to exclude from that subsequence, $b_l, ..., b_r$, where $b_1, ... , b_n$ is the sequence after applying all the updates that come before the query. $1 \leq l, 0 \leq k \leq 2$, and $l + k \leq r \leq n$ hold.
Output
No output is required for update instructions. For each of the query instructions, output a line with the LCM of the GCDs of the sets of the items in all the subsequences made by excluding
$k$ items from the sequence $b_l, ..., b_r$.
Sample Input 1
5 10
12 10 16 28 15
Q 1 3 1
Q 3 4 0
Q 2 2 0
Q 2 5 2
U 3 21
Q 1 3 1
Q 2 4 1
Q 3 5 1
Q 4 4 0
Q 2 5 2
Sample Output 1
4
4
10
20
6
14
21
28
210
For the first query of this test case, "
Q 1 3 1
", the subsequence is 12 10 16. Eliminating a single item results in three item sets, {12, 10}, {12, 16}, and {10, 16}. Their GCDs are 2, 4, and 2, respectively, and thus the output should be their LCM, 4.
Note that, the update given as the fifth instruction, "
U 3 21
", changes the answer to the same query, "
Q 1 3 1
", given as the sixth instruction. The update makes the subsequence to 12 10 21. Thus the item sets after eliminating a single item are {12, 10}, {12, 21}
...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < (ll)n; ++i)

template <typename T>
class segtree {
  protected:
    const T E;
    vector<T> _data;
    const function<T(T,T)> _query;
    int _length;

    T _query_sub(int a, int b, int k, int l, int r) const {
        if (r <= a || b <= l) {
            return E;
        }
        else if (a <= l && r <= b) {
            return _data[k];
        }
        else {
            T vl = _query_sub(a, b, k * 2 + 1, l , (l + r) / 2);
            T vr = _query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
            return _query(vl, vr);
        }
    }

    public:
    segtree(int len, T e, function<T(T,T)> query) : E(e), _query(move(query)), _length(1) {
        while (_length < len) {
            _length <<= 1;
        }
        _data.assign(_length * 2 - 1, E);
    }

    size_t size() const {return _length;}

    T &operator[](size_t i) {
        if (i < 0 || i >= _length) throw out_of_range("Index out of range");
        return _data[i + _length - 1];
    }

    void build() {
        for (int i = _length - 2; i >= 0; --i) {
            _data[i] = _query(_data[i * 2 + 1], _data[i * 2 + 2]);
        }
    }

    void update(int i, T value) {
        if (i < 0 || i >= _length) throw out_of_range("Index out of range");
        i += _length - 1;
        _data[i] = value;
        while (i > 0) {
            i = (i - 1) >> 1;
            _data[i] = _query(_data[i * 2 + 1], _data[i * 2 + 2]);
        }
    }

    T query(int a, int b) const {
        if (a < 0 || b < 0 || a > _length || b > _length) throw out_of_range("Index out of range");
        return _query_sub(a, b, 0, 0, _length);
    }
};

struct Data {
    vector<pair<int, int>> cnt;
    int size;

    Data() : cnt(vector<pair<int, int>>()), size(0) {}
    Data(vector<pair<int, int>> cnt, int size) : cnt(cnt), size(size) {}
};

int main() {
    int n, m; cin >> n >> m;
    vector<int> a(n);
    rep(i, n) cin >> a[i];

    vector<vector<int>> divs(1e6 + 1);
    for (int i = 2; i <= 1e6; ++i) {
        for (int j = i; j <= 1e6; j += i) {
            divs[j].push_back(i);
        }
    }

    segtree<Data> seg(n, Data(), [](Data a, Data b) -> Data {
        int nsize = a.size + b.size;
        sort(a.cnt.rbegin(), a.cnt.rend());
        sort(b.cnt.rbegin(), b.cnt.rend());
        
        vector<pair<int, int>> res;
        while (a.cnt.size() > 0 || b.cnt.size() > 0) {
            auto [aval, acnt] = a.cnt.size() > 0 ? a.cnt.back() : make_pair(2002002002, 0);
            auto [bval, bcnt] = b.cnt.size() > 0 ? b.cnt.back() : make_pair(2002002002, 0);
            if (aval == bval) {
                if (nsize - 2 <= acnt + bcnt) res.push_back({aval, acnt + bcnt});
                a.cnt.pop_back();
                b.cnt.pop_back();
            }
            else if (aval < bval) {
                if (nsize - 2 <= acnt) res.push_back({aval, acnt});
                a.cnt.pop_back();
            }
            else {
                if (nsize - 2 <= bcnt) res.push_back({bval, bcnt});
                b.cnt.pop_back();
            }
        }

        return Data(res, nsize);
    });

    rep(i, n) {
        vector<pair<int, int>> cnt;
        for (ll v : divs[a[i]]) {
            cnt.push_back({v, 1});
        }
        seg[i] = Data(cnt, 1);
    }
    seg.build();

    rep(i, m) {
        char t; cin >> t;
        if (t == 'U') {
            ll j, x; cin >> j >> x;
            --j;

            vector<pair<int, int>> cnt;
            for (ll v : divs[x]) {
                cnt.push_back({v, 1});
            }
            seg.update(j, {cnt, 1});
        }
        else {
            ll l, r, k; cin >> l >> r >> k;
            --l;
            Data d = seg.query(l, r);

            long long ans = 1;
            for (auto [v, c] : d.cnt) {
                if (c < d.size - k) continue;
                ans = lcm(ans, (long long)v);
            }
            cout << ans << "\n";
        }
    }

    return 0;
}
accuracy: 1
time_ms: 1730
memory_kb: 183044
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = int;
#define rep(i, n) for (ll i = 0; i < (ll)n; ++i)

template <typename T>
class segtree {
  protected:
    const T E;
    vector<T> _data;
    const function<T(T,T)> _query;
    int _length;

    T _query_sub(int a, int b, int k, int l, int r) const {
        if (r <= a || b <= l) {
            return E;
        }
        else if (a <= l && r <= b) {
            return _data[k];
        }
        else {
            T vl = _query_sub(a, b, k * 2 + 1, l , (l + r) / 2);
            T vr = _query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
            return _query(vl, vr);
        }
    }

    public:
    segtree(int len, T e, function<T(T,T)> query) : E(e), _query(move(query)), _length(1) {
        while (_length < len) {
            _length <<= 1;
        }
        _data.assign(_length * 2 - 1, E);
    }

    size_t size() const {return _length;}

    T &operator[](size_t i) {
        if (i < 0 || i >= _length) throw out_of_range("Index out of range");
        return _data[i + _length - 1];
    }

    void build() {
        for (int i = _length - 2; i >= 0; --i) {
            _data[i] = _query(_data[i * 2 + 1], _data[i * 2 + 2]);
        }
    }

    void update(int i, T value) {
        if (i < 0 || i >= _length) throw out_of_range("Index out of range");
        i += _length - 1;
        _data[i] = value;
        while (i > 0) {
            i = (i - 1) >> 1;
            _data[i] = _query(_data[i * 2 + 1], _data[i * 2 + 2]);
        }
    }

    T query(int a, int b) const {
        if (a < 0 || b < 0 || a > _length || b > _length) throw out_of_range("Index out of range");
        return _query_sub(a, b, 0, 0, _length);
    }
};

struct Data {
    map<ll, ll> cnt;
    ll size;

    Data() : cnt(map<ll, ll>()), size(0) {}
    Data(map<ll, ll> cnt, ll size) : cnt(cnt), size(size) {}
};

int main() {
    ll n, m; cin >> n >> m;
    vector<ll> a(n);
    rep(i, n) cin >> a[i];

    vector<vector<ll>> divs(1e6 + 1);
    for (int i = 2; i <= 1e6; ++i) {
        for (int j = i; j <= 1e6; j += i) {
            divs[j].push_back(i);
        }
    }

    segtree<Data> seg(n, Data(), [](Data a, Data b) -> Data {
        a.size += b.size;
        for (auto [v, cnt] : b.cnt) {
            a.cnt[v] += cnt;
        }

        map<ll, ll> res;
        for (auto [v, cnt] : a.cnt) {
            if (cnt < a.size - 2) continue;
            res[v] = cnt;
        }
        a.cnt = res;

        return a;
    });

    rep(i, n) {
        map<ll, ll> cnt;
        for (ll v : divs[a[i]]) {
            cnt[v]++;
        }
        seg[i] = Data(cnt, 1);
    }
    seg.build();

    rep(i, m) {
        char t; cin >> t;
        if (t == 'U') {
            ll j, x; cin >> j >> x;
            --j;

            map<ll, ll> cnt;
            for (ll v : divs[x]) {
                cnt[v]++;
            }
            seg.update(j, {cnt, 1});
        }
        else {
            ll l, r, k; cin >> l >> r >> k;
            --l;
            Data d = seg.query(l, r);

            ll ans = 1;
            for (auto [v, c] : d.cnt) {
                if (c < d.size - k) continue;
                ans = lcm(ans, v);
            }
            cout << ans << "\n";
        }
    }

    return 0;
}
accuracy: 0.07142857142857142
time_ms: 2010
memory_kb: 250924
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) begin(x), end(x)
#define rep(i, l, r) for (int i = (l), i##end = (r); i <= i##end; ++i)
#define per(i, l, r) for (int i = (l), i##end = (r); i >= i##end; --i)
#ifdef memset0
#define log(...) fprintf(stderr, __VA_ARGS__)
#else
#define log(...) (void(0))
#define endl '\n'
#endif
using namespace std;
// using ll = long long;
// using lf = long double;
// using lll = __int128;
// using ull = unsigned long long;

using ll = __int128;

#define putc putchar
void write(ll x) {
  if (x == 0) {
    putc('0');
    return;
  }
  if (x > 9) write(x / 10);
  putc('0' + x % 10);
}

const int N = 1e5 + 9;
int n, m;
ll a[N];
string op;

ll GCD(ll a, ll b) {
  if (!a) return b;
  if (!b) return a;
  return __gcd(a, b);
}
ll LCM(ll a, ll b) {
  if (!a) return b;
  if (!b) return a;
  return a / GCD(a, b) * b;
}
struct atom {
  ll v[3];
  int len;
  void set(ll x) {
    v[0] = x, v[1] = v[2] = 0;
    len = 1;
  }
};
atom operator^(const atom &a, const atom &b) {
  atom res;
  res.v[0] = GCD(a.v[0], b.v[0]);
  res.v[1] = LCM(GCD(a.v[0], b.v[1]), GCD(a.v[1], b.v[0]));
  res.v[2] = GCD(a.v[1], b.v[1]);
  if (a.len >= 2) res.v[2] = LCM(res.v[2], GCD(a.v[2], b.v[0]));
  if (b.len >= 2) res.v[2] = LCM(res.v[2], GCD(a.v[0], b.v[2]));
  res.len = a.len + b.len;
  return res;
}

struct segment {
  int l, r, mid;
  atom x;
} p[N << 2];

void build(int u, int l, int r) {
  p[u].l = l, p[u].r = r, p[u].mid = (l + r) >> 1;
  if (l == r) {
    p[u].x.set(a[l]);
    // cerr << "! " << a[l] << endl;
    // log("[%d %d] >> %lld %lld %lld\n", p[u].l, p[u].r, p[u].x[0], p[u].x[1], p[u].x[2]);
    return;
  }
  build(u << 1, l, p[u].mid);
  build(u << 1 | 1, p[u].mid + 1, r);
  p[u].x = p[u << 1].x ^ p[u << 1 | 1].x;
  // log("[%d %d] >> %lld %lld %lld\n", p[u].l, p[u].r, (long long)p[u].x[0], (long long)p[u].x[1], (long long)p[u].x[2]);
}

void modify(int u, int k) {
  if (p[u].l == p[u].r) {
    p[u].x.set(a[p[u].l]);
    return;
  }
  if (k <= p[u].mid) {
    modify(u << 1, k);
  } else {
    modify(u << 1 | 1, k);
  }
  p[u].x = p[u << 1].x ^ p[u << 1 | 1].x;
}

atom query(int u, int l, int r) {
  if (p[u].l == l && p[u].r == r) {
    return p[u].x;
  }
  if (r <= p[u].mid) return query(u << 1, l, r);
  if (l > p[u].mid) return query(u << 1 | 1, l, r);
  return query(u << 1, l, p[u].mid) ^ //
         query(u << 1 | 1, p[u].mid + 1, r);
}

int main() {
#ifdef memset0
  freopen("H.in", "r", stdin);
#endif
  cin.tie(0)->sync_with_stdio(0);
  cin >> n >> m;
  for (int x, i = 1; i <= n; i++) {
    cin >> x;
    a[i] = x;
  }
  build(1, 1, n);
  for (int l, r, k, x, i = 1; i <= m; i++) {
    cin >> op;
    if (op[0] == 'U') {
      cin >> k >> x;
      a[k] = x;
      modify(1, k);
    } else {
      cin >> l >> r >> k;
      auto it = query(1, l, r);
      write(it.v[k]), putc('\n');
    }
  }
}
accuracy: 1
time_ms: 240
memory_kb: 28084
final_rank: 7

code_snippet: // Yokohama 2020 H LCM of GCDs
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; }
LL lcm(LL a, LL b) { return (!a || !b) ? 0 : a / gcd(a, b) * b; }
using Node = array<LL, 3>;                      // [X0, X1, X2]
Node operator+(const Node& a, const Node& b) {  // 合并两段
  return {gcd(a[0], b[0]), lcm(gcd(a[0], b[1]), gcd(b[0], a[1])),
          lcm(gcd(a[1], b[1]), lcm(gcd(a[0], b[2]), gcd(a[2], b[0])))};
}
struct SegTree {
  int n;           // 原数组长度
  vector<Node> T;  // 4n 足够存树
  SegTree(int sz) : n(sz), T(sz * 4, Node{0, 0, 0}) {}
  LL update(int o, int L, int R, int x, LL val) { /* 把 a[x] ← val */
    if (L == R) return T[o] = {val, 0, 0}, 0;
    int lc = 2 * o, rc = 2 * o + 1, m = (L + R) / 2;
    x <= m ? update(lc, L, m, x, val) : update(rc, m + 1, R, x, val);
    return T[o] = T[lc] + T[rc], 0;
  }
  /* 区间查询 [L,R] ，若与当前区间无交返回 {0,0,0}（单位元） */
  Node query(int o, int L, int R, int qL, int qR) const {
    if (qR < L || R < qL) return Node{0, 0, 0};  // 不相交
    if (qL <= L && R <= qR) return T[o];         // 完全包含
    int lc = 2 * o, rc = 2 * o + 1, m = (L + R) / 2;
    return query(lc, L, m, qL, qR) + query(rc, m + 1, R, qL, qR);
  }
  void update(int idx, LL val) { update(1, 1, n, idx, val); }
  Node query(int l, int r) const { return query(1, 1, n, l, r); }
};
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n, m;
  cin >> n >> m;
  SegTree T(n);
  for (int i = 1, a; i <= n; i++) cin >> a, T.update(i, a);
  for (char op; m-- and cin >> op;) {
    if (op == 'U') {  // Update
      int x, v;
      cin >> x >> v, T.update(x, v);  // 1-based → 0-based
    } else {                          // Query
      int l, r, k;
      cin >> l >> r >> k, printf("%lld\n", T.query(l, r)[k]);
    }
  }
  return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 12592
final_rank: 6

code_snippet: #line 1 "main.cpp"
#include <bits/stdc++.h>
#line 2 "/home/nixos/workspace/CompPro-Make/library/rainbou/cpp/segtree.hpp"

/**
 * @file segtree.hpp
 * @brief πé╗πé░πâíπâ│πâêµ£¿
 */

#line 13 "/home/nixos/workspace/CompPro-Make/library/rainbou/cpp/segtree.hpp"

/**
 * @brief πé╗πé░πâíπâ│πâêµ£¿πü«CRTPσƒ║σ║òπé»πâ⌐πé╣
 * 
 * @tparam S πâóπâÄπéñπâëπü«σ₧ï
 * @tparam ActualSegTree µ┤╛τöƒπé»πâ⌐πé╣
 */
template <typename S, typename ActualSegTree>
class SegTreeBase {
    S op(const S& a, const S& b) const { return static_cast<const ActualSegTree&>(*this).op(a, b); }
    S e() const { return static_cast<const ActualSegTree&>(*this).e(); }

    int n, sz, height;
    std::vector<S> data;
    void update(int k) { data[k] = op(data[2 * k], data[2 * k + 1]); }

    class SegTreeReference {
        SegTreeBase& segtree;
        int k;
    public:
        SegTreeReference(SegTreeBase& segtree, int k) : segtree(segtree), k(k) {}
        SegTreeReference& operator=(const S& x) {
            segtree.set(k, x);
            return *this;
        }
        operator S() const { return segtree.get(k); }
    };

protected:
    void construct_data() {
        sz = 1;
        height = 0;
        while (sz < n) {
            sz <<= 1;
            height++;
        }
        data.assign(sz * 2, e());
    }
    void initialize(const std::vector<S>& v) {
        for (int i = 0; i < n; i++) data[sz + i] = v[i];
        for (int i = sz - 1; i > 0; i--) update(i);
    }

public:
    // Warning: τ╢Öµë┐σàêπü«πé│πâ│πé╣πâêπâ⌐πé»πé┐πüºconstruct_data()πéÆσ┐àπüÜσæ╝πü│σç║πüÖ∩╝ü
    SegTreeBase(int n = 0) : n(n) {}

    /**
     * @brief µîçσ«ÜπüòπéîπüƒΦªüτ┤áπü«σÇñπéÆΦ┐öπüÖ
     * 
     * @param k πéñπâ│πâçπââπé»πé╣
     * @return S σÇñ
     */
    S get(int k) const { return data[sz + k]; }
    /**
     * @brief µîçσ«ÜπüòπéîπüƒΦªüτ┤áπü«σÇñπéÆΦ┐öπüÖ
     * 
     * @param k πéñπâ│πâçπââπé»πé╣
     * @return S σÇñ
     */
    S operator[] (int k) const { return get(k); }
    /**
     * @brief µîçσ«ÜπüòπéîπüƒΦªüτ┤áπü╕πü«σÅéτàºπéÆΦ┐öπüÖ
     * 
     * @param k 
     * @return SegTreeReference Φªüτ┤áπü╕πü«σÅéτàº Σ╗úσàÑπüòπéîπéïπü¿set()πüîσæ╝πü░πéîπéï
     */
    SegTreeReference operator[] (int k) { return SegTreeReference(*this, k); }

    /**
     * @brief σåàσ«╣πéÆσç║σè¢πüÖπéï
     * 
     * @tparam CharT σç║σè¢πé╣πâêπâ¬πâ╝πâáπü«µûçσ¡ùσ₧ï
     * @tparam Traits σç║σè¢πé╣πâêπâ¬πâ╝πâáπü«µûçσ¡ùσ₧ïτë╣µÇº
     * @param os σç║σè¢πé╣πâêπâ¬πâ╝πâá
     * @param rhs πé╗πé░πâíπâ│πâêµ£¿
     * @return std::basic_ostream<CharT, Traits>& σç║σè¢πé╣πâêπâ¬πâ╝πâá 
     */
    template <class CharT, class Traits>
    friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const SegTreeBase& rhs) {
        for(int i = 0; i < rhs.n; i++) {
            if(i != 0) os << CharT(' ');
            os << rhs[i];
        }
        return os;
    }

    /**
     * @brief µîçσ«ÜπüòπéîπüƒΦªüτ┤áπü«σÇñπéÆxπü½µ¢┤µû░πüÖπéï
     * 
     * @param k πéñπâ│πâçπââπé»πé╣
     * @param x µû░πüùπüäσÇñ
     */
    void set(int k, const S& x) {
        k += sz;
        data[k] = x;
        for (int i = 1; i <= height; i++) update(k >> i);
    }
    /**
     * @brief µîçσ«ÜπüòπéîπüƒΦªüτ┤áπü«σÇñπü½xπéÆΣ╜£τö¿πüòπü¢πéï
     * 
     * @param k πéñπâ│πâçπââπé»πé╣
     * @param x Σ╜£τö¿τ┤á
     */
    void apply(int k, const S& x) { set(k, op(get(k), x)); }

    /**
     * @brief [l, r)πü«σî║Θûôπü«τ╖Åτ⌐ìπéÆΦ┐öπüÖ
     * 
     * @param l σìèΘûïσî║Θûôπü«Θûïσºï
     * @param r σìèΘûïσî║Θûôπü«τ╡éτ½»
     * @return S τ╖Åτ⌐ì
     */
    S prod(int l, int r) const {
        S left_prod = e(), right_prod = e();
        l += sz;
        r += sz;
        while (l < r) {
            if (l & 1) left_prod = op(left_prod, data[l++]);
            if (r & 1) right_prod = op(data[--r], right_prod);
            l >>= 1;
            r >>= 1;
        }
        return op(left_prod, right_prod);
    }
    /**
     * @brief πüÖπü╣πüªπü«Φªüτ┤áπü«τ╖Åτ⌐ìπéÆΦ┐öπüÖ
     * 
     * @return S τ╖Åτ⌐ì
     */
    S all_prod() const { return data[1]; }

    /**
     * @brief (r = l or f(prod([l, r))) = true) and (r = n or f(prod([l, r+1))) = false)πü¿πü¬πéïrπéÆΦ┐öπüÖ
     * fπüîσìÿΦ¬┐πü¬πéëπÇüf(prod([l, r))) = trueπü¿πü¬πéïµ£Çσñºπü«r
     * 
     * @tparam F
     * @param l σìèΘûïσî║Θûôπü«Θûïσºï
     * @param f σêñσ«ÜΘûóµò░ f(e) = true
     * @return int
     */
    template <typename F>
    int max_right(int l, F f) const {
        assert(f(e()));
        if (l == n) return n;
        l += sz;
        while (l % 2 == 0) l >>= 1;
        S sum = e();
        while(f(op(sum, data[l]))) {
            sum = op(sum, data[l]);
            l++;
            while (l % 2 == 0) l >>= 1;
            if (l == 1) return n;
        }
        while (l < sz) {
            if (!f(op(sum, data[l * 2]))) l *= 2;
            else {
                sum = op(sum, data[l * 2]);
                l = l * 2 + 1;
            }
        }
        return l - sz;
    }
    /**
     * @brief (l = 0 or f(prod([l, r))) = true) and (l = r or f(prod([l-1, r))) = false)πü¿πü¬πéïlπéÆΦ┐öπüÖ
     * fπüîσìÿΦ¬┐πü¬πéëπÇüf(prod([l, r))) = trueπü¿πü¬πéïµ£Çσ░Åπü«l
     * 
     * @tparam F
     * @param r σìèΘûïσî║Θûôπü«τ╡éτ½»
     * @param f σêñσ«ÜΘûóµò░ f(e) = true
     * @return int
     */
    template <typename F>
    int min_left(int r, F f) const {
        assert(f(e()));
        if (r == 0) return 0;
        r += sz;
        while (r % 2 == 0) r >>= 1;
        S sum = e();
        while(f(op(data[r-1], sum))) {
            sum = op(data[r-1], sum);
            r--;
            while (r % 2 == 0) r >>= 1;
            if (r == 1) return 0;
        }
        while (r < sz) {
            if (!f(op(data[r * 2 - 1], sum))) r *= 2;
            else {
                sum = op(data[r * 2 - 1], sum);
                r = r * 2 - 1;
            }
        }
        return r - sz;
    }
};

/**
 * @brief τ⌐ìπü«πâòπéíπâ│πé»πé┐πüîΘ¥ÖτÜäπü¬σá┤σÉêπü«πé╗πé░πâíπâ│πâêµ£¿πü«σ«ƒΦúà
 * 
 * @tparam S πâóπâÄπéñπâëπü«σ₧ï
 * @tparam Op τ⌐ìπü«πâòπéíπâ│πé»πé┐
 * @tparam E τ⌐ìπü«σìÿΣ╜ìσàâπéÆΦ┐öπüÖπâòπéíπâ│πé»πé┐
 */
template <typename S, typename Op, typename E>
class StaticSegTree : public SegTreeBase<S, StaticSegTree<S, Op, E>> {
    using BaseType = SegTreeBase<S, StaticSegTree<S, Op, E>>;

    inline static Op operator_object;
    inline static E identity_object;
public:
    S op(const S& a, const S& b) const { return operator_object(a, b); }
    S e() const { return identity_object(); }

    /**
     * @brief πâçπâòπé⌐πâ½πâêπé│πâ│πé╣πâêπâ⌐πé»πé┐
     * 
    */
    StaticSegTree() = default;
    /**
     * @brief πé│πâ│πé╣πâêπâ⌐πé»πé┐
     * 
     * @param n Φªüτ┤áµò░
     */
    explicit StaticSegTree(int n) : BaseType(n) {
        this->construct_data();
    }
    /**
     * @brief πé│πâ│πé╣πâêπâ⌐πé»πé┐
     * 
     * @param v σê¥µ£ƒπü«Φªüτ┤á
     */
    explicit StaticSegTree(const std::vector<S>& v) : StaticSegTree(v.size()) {
        this->initialize(v);
    }
};

/**
 * @brief πé│πâ│πé╣πâêπâ⌐πé»πé┐πüºΘûóµò░πé¬πâûπé╕πéºπé»πâêπéÆΣ╕Äπüêπéïπüôπü¿πüºτ⌐ìπéÆσ«Üτ╛⌐πüÖπéïπé╗πé░πâíπâ│πâêµ£¿πü«σ«ƒΦúà
 * πâåπâ│πâùπâ¼πâ╝πâêσ╝òµò░πéÆτ£üτòÑπüÖπéïπüôπü¿πüîπüºπüìπÇüπâ⌐πâáπâÇσ╝ÅπüîΣ╜┐πüêπéï
 * 
 * @tparam S πâóπâÄπéñπâëπü«σ₧ï
 * @tparam Op τ⌐ìπü«Θûóµò░πé¬πâûπé╕πéºπé»πâêπü«σ₧ï
 */
template <typename S, typename Op>
class SegTree : public SegTreeBase<S, SegTree<S, Op>> {
    using BaseType = SegTreeBase<S, SegTree<S, Op>>;

    Op operator_object;
    S identity;

public:
    S op(const S& a, const S& b) const { return operator_object(a, b); }
    S e() const { return identity; }

    /**
     * @brief πâçπâòπé⌐πâ½πâêπé│πâ│πé╣πâêπâ⌐πé»πé┐
    */
    SegTree() = default;
    /**
     * @brief πé│πâ│πé╣πâêπâ⌐πé»πé┐
     * 
     * @param n Φªüτ┤áµò░
     * @param op τ⌐ìπü«Θûóµò░πé¬πâûπé╕πéºπé»πâê
     * @param identity σìÿΣ╜ìσàâ
     */
    explicit SegTree(int n, Op op, const S& identity) : BaseType(n), operator_object(std::move(op)), identity(identity) {
        this->construct_data();
    }
    /**
     * @brief πé│πâ│πé╣πâêπâ⌐πé»πé┐
     * 
     * @param v σê¥µ£ƒπü«Φªüτ┤á
     * @param op τ⌐ìπü«Θûóµò░πé¬πâûπé╕πéºπé»πâê
     * @param identity σìÿΣ╜ìσàâ
     */
    explicit SegTree(const std::vector<S>& v, Op op, const S& identity) : SegTree(v.size(), std::move(op), identity) {
        this->initialize(v);
    }
};

namespace segtree {
    template <typename S>
    struct Max {
        const S operator() (const S& a, const S& b) const { return std::max(a, b); }
    };
    template <typename S>
    struct Min {
        const S operator() (const S& a, const S& b) const { return std::min(a, b); }
    };
    template <typename S, std::enable_if_t<std::is_scalar_v<S>>* = nullptr>
    struct MaxLimit {
        constexpr S operator() () const { return std::numeric_limits<S>::max(); }
    };
    template <typename S, std::enable_if_t<std::is_scalar_v<S>>* = nullptr>
    struct MinLimit {
        constexpr S operator() () const { return std::numeric_limits<S>::lowest(); }
    };
    template <typename S>
    struct Zero {
        S operator() () const { return S(0); }
    };
}
/**
 * @brief RangeMaxQuery
 * 
 * @tparam S σ₧ï
 */
template <typename S>
using RMaxQ = StaticSegTree<S, segtree::Max<S>, segtree::MinLimit<S>>;
/**
 * @brief RangeMinQuery
 * 
 * @tparam S σ₧ï
 */
template <typename S>
using RMinQ = StaticSegTree<S, segtree::Min<S>, segtree::MaxLimit<S>>;
/**
 * @brief RangeSumQuery
 * 
 * @tparam S σ₧ï
 */
template <typename S>
using RSumQ = StaticSegTree<S, std::plus<S>, segtree::Zero<S>>;
#line 3 "main.cpp"
using namespace std;
using ll = long long;
constexpr ll MOD = 998244353;

int main() {
    int n, m; cin >> n >> m;
    vector<ll> a(n);
    for(int i = 0; i < n; i++) cin >> a[i];
    SegTree seg(a, [](ll l, ll r) { return gcd(l, r); }, 0LL);
    auto div = [&](ll x) {
        vector<ll> ret;
        for(ll i = 1; i*i <= x; i++) {
            if(x % i == 0) {
                ret.push_back(i);
                if(i*i < x) ret.push_back(x / i);
            }
        }
        return ret;
    };
    vector<vector<ll>> divisors(n);
    for(int i = 0; i < n; i++) divisors[i] = div(a[i]);
    while(m--) {
        char op; cin >> op;
        if(op == 'U') {
            int j; ll x; cin >> j >> x; j--;
            seg.set(j, x);
            divisors[j] = div(x);
        } else {
            int l, r, k; cin >> l >> r >> k; l--;
            ll ret = 1;
            vector<ll> cand;
            for(int idx = l; idx <= l+k && idx < r; idx++) {
                for(ll d : divisors[idx]) {
                    cand.push_back(d);
                }
            }
            ranges::sort(cand);
            cand.erase(ranges::unique(cand).begin(), cand.end());
            for(ll d : cand) {
                int cur = l;
                for(int t = 0; t <= k; t++) {
                    cur = seg.max_right(cur, [&](ll x) { return x % d == 0; });
                    if(t < k && cur+1 <= r) cur++;
                }
                if(cur >= r) ret = lcm(ret, d);
            }
            cout << ret << '\n';
        }
    }
}
accuracy: 1
time_ms: 630
memory_kb: 49628
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;

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

using Node=array<ll,3>;
Node op(Node l,Node r){
	//各素因数について小さい方から3つ
	ll m0=gcd(l[0],r[0]);
	ll m1=lcm(gcd(l[0],r[1]),gcd(l[1],r[0]));
	ll m2=lcm(gcd(l[0],r[2]),gcd(l[1],r[1]),gcd(l[2],r[0]));
	return {m0,m1,m2};
}
Node e(){return {0,0,0};}

struct Seg{
	int n;
	vector<Node>dat;
	Seg(const vector<Node>&v){
		n=v.size();
		dat.resize(2*n);
		for(int i=0;i<n;i++)dat[i+n]=v[i];
		for(int i=n-1;i>0;i--)dat[i]=op(dat[i*2],dat[i*2+1]);
	}
	void set(int i,Node x){
		dat[i+=n]=x;
		while(i>>=1)dat[i]=op(dat[i*2],dat[i*2+1]);
	}
	Node fold(int l,int r){
		l+=n,r+=n;
		Node ret=e();
		while(l<r){
			if(l&1)ret=op(ret,dat[l++]);
			if(r&1)ret=op(ret,dat[--r]);
			l>>=1,r>>=1;
		}
		return ret;
	}
};

int main(){
	int N,Q;cin>>N>>Q;
	vector<Node>A(N);
	for(int i=0;i<N;i++){
		int a;cin>>a;
		A[i]={a,0,0};
	}
	Seg seg(A);

	while(Q--){
		char t;cin>>t;
		
		if(t=='U'){
			int i,x;cin>>i>>x;
			i--;

			seg.set(i,{x,0,0});
		}

		else{
			int l,r,k;cin>>l>>r>>k;
			l--;

			cout<<seg.fold(l,r)[k]<<'\n';
		}
	}
}
accuracy: 1
time_ms: 270
memory_kb: 10144
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;

ll lcm(ll a,ll b){
	if(a==0)return b;
	if(b==0)return a;
	return a/gcd(a,b)*b;
}
ll lcm(ll a,ll b,ll c){return lcm(a,lcm(b,c));}

using Node=array<ll,3>;
Node op(Node l,Node r){
	//各素因数について小さい方から3つ
	vector<ll>lr;
	for(int i=0;i<3;i++){
		if(l[i]!=0)lr.push_back(l[i]);
		if(r[i]!=0)lr.push_back(r[i]);
	}
	ll m0=0,m1=0,m2=0;

	for(ll x:lr)m0=gcd(m0,x);

	vector<ll>m1s;
	for(int i=0;i<lr.size();i++){
		for(int j=i+1;j<lr.size();j++){
			m1s.push_back(lcm(lr[i],lr[j]));
		}
	}
	for(ll x:m1s)m1=gcd(m1,x);

	vector<ll>m2s;
	for(int i=0;i<lr.size();i++){
		for(int j=i+1;j<lr.size();j++){
			for(int k=j+1;k<lr.size();k++){
				m2s.push_back(lcm(lr[i],lr[j],lr[k]));
			}
		}
	}
	for(ll x:m2s)m2=gcd(m2,x);

	return {m0,m1,m2};
}
Node e(){return {0,0,0};}

struct Seg{
	int n;
	vector<Node>dat;
	Seg(const vector<Node>&v){
		n=v.size();
		dat.resize(2*n);
		for(int i=0;i<n;i++)dat[i+n]=v[i];
		for(int i=n-1;i>0;i--)dat[i]=op(dat[i*2],dat[i*2+1]);
	}
	void set(int i,Node x){
		dat[i+=n]=x;
		while(i>>=1)dat[i]=op(dat[i*2],dat[i*2+1]);
	}
	Node fold(int l,int r){
		l+=n,r+=n;
		Node ret=e();
		while(l<r){
			if(l&1)ret=op(ret,dat[l++]);
			if(r&1)ret=op(ret,dat[--r]);
			l>>=1,r>>=1;
		}
		return ret;
	}
};

int main(){
	int N,Q;cin>>N>>Q;
	vector<Node>A(N);
	for(int i=0;i<N;i++){
		int a;cin>>a;
		A[i]={a,0,0};
	}
	Seg seg(A);

	while(Q--){
		char t;cin>>t;
		
		if(t=='U'){
			int i,x;cin>>i>>x;
			i--;

			seg.set(i,{x,0,0});
		}

		else{
			int l,r,k;cin>>l>>r>>k;
			l--;

			cout<<seg.fold(l,r)[k]<<'\n';
		}
	}
}
accuracy: 0.07142857142857142
time_ms: 1620
memory_kb: 10052
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;

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

using Node=array<ll,3>;
Node op(Node l,Node r){
	//各素因数について小さい方から3つ
	vector<ll>lr;
	for(int i=0;i<3;i++){
		if(l[i]!=0)lr.push_back(l[i]);
		if(r[i]!=0)lr.push_back(r[i]);
	}
	ll m0=0,m1=0,m2=0;

	for(ll x:lr)m0=gcd(m0,x);

	vector<ll>m1s;
	for(int i=0;i<lr.size();i++){
		for(int j=i+1;j<lr.size();j++){
			m1s.push_back(lcm(lr[i],lr[j]));
		}
	}
	for(ll x:m1s)m1=gcd(m1,x);

	vector<ll>m2s;
	for(int i=0;i<lr.size();i++){
		for(int j=i+1;j<lr.size();j++){
			for(int k=j+1;k<lr.size();k++){
				m2s.push_back(lcm(lr[i],lr[j],lr[k]));
			}
		}
	}
	for(ll x:m2s)m2=gcd(m2,x);

	return {m0,m1,m2};
}
Node e(){return {0,0,0};}

struct Seg{
	int n;
	vector<Node>dat;
	Seg(const vector<Node>&v){
		n=v.size();
		dat.resize(2*n);
		for(int i=0;i<n;i++)dat[i+n]=v[i];
		for(int i=n-1;i>0;i--)dat[i]=op(dat[i*2],dat[i*2+1]);
	}
	void set(int i,Node x){
		dat[i+=n]=x;
		while(i>>=1)dat[i]=op(dat[i*2],dat[i*2+1]);
	}
	Node fold(int l,int r){
		l+=n,r+=n;
		Node ret=e();
		while(l<r){
			if(l&1)ret=op(ret,dat[l++]);
			if(r&1)ret=op(ret,dat[--r]);
			l>>=1,r>>=1;
		}
		return ret;
	}
};

int main(){
	int N,Q;cin>>N>>Q;
	vector<Node>A(N);
	for(int i=0;i<N;i++){
		int a;cin>>a;
		A[i]={a,0,0};
	}
	Seg seg(A);

	while(Q--){
		char t;cin>>t;
		
		if(t=='U'){
			int i,x;cin>>i>>x;
			i--;

			seg.set(i,{x,0,0});
		}

		else{
			int l,r,k;cin>>l>>r>>k;
			l--;

			cout<<seg.fold(l,r)[k]<<'\n';
		}
	}
}
accuracy: 0.07142857142857142
time_ms: 1560
memory_kb: 9984
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,a,b) for(ll i = a; i < b; i++)
#define all(a) a.begin(), a.end()

using ull = unsigned long long;
using S = array<ull, 3>;

S e(){
    return {0,0,0};
}


S op(S a, S b){
    S res;
    res[0] = gcd(a[0], b[0]);
    res[1] = gcd(lcm(a[0], b[0]), gcd(a[1], b[1]));
    res[2] = gcd(gcd(lcm(a[0],b[1]), lcm(a[1],b[0])), gcd(a[2], b[2]));
    return res;
}

template<typename S, S (*op)(S, S), S (*e)()> class SegmentTree {
   private:
   int _n, sz;
   vector<S> data;

   void calc(int k) { data[k] = op(data[k << 1], data[k << 1 | 1]); }

   public:
   SegmentTree() = default;
   explicit SegmentTree(int n) : SegmentTree(vector<S>(n, e())) {}
   explicit SegmentTree(const vector<S>& v) : _n(v.size()) {
      sz = 1;
      while(sz < _n) sz <<= 1;
      data.assign(sz << 1, e());
      for(int i = 0; i < _n; i++) data[sz + i] = v[i];
      for(int i = sz - 1; i >= 1; i--) calc(i);
   }

   void set(int p, S x) {
      assert(0 <= p && p < _n);
      p += sz;
      data[p] = x;
      while(p >>= 1) calc(p);
   }

   S get(int p) {
      assert(0 <= p && p < _n);
      return data[p + sz];
   }

   S prod(int l, int r) {
      assert(0 <= l && l <= r && r <= _n);
      S sl = e(), sr = e();
      l += sz;
      r += sz;
      while(l < r) {
         if(l & 1) sl = op(sl, data[l++]);
         if(r & 1) sr = op(data[--r], sr);
         l >>= 1;
         r >>= 1;
      }
      return op(sl, sr);
   }

   S all_prod() { return data[1]; }
};

int main(){
    int n,m;
    cin >> n >> m;
    vector<ull> res(n);
    rep(i,0,n) cin >> res[i];
    SegmentTree<S,op,e> tree(n);
    rep(i,0,n) tree.set(i, {res[i],0,0});

    while(m--){
        char t;
        cin >> t;
        if(t == 'Q'){
            int l,r,k;
            cin >> l >> r >> k;
            l--;
            S d = tree.prod(l,r);
            cout << d[k] << endl;
        }else{
            ull i,x;
            cin >> i >> x;
            i--;
            tree.set(i, {x,0,0});
        }
    }
}
accuracy: 1
time_ms: 170
memory_kb: 12592
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

// base: bafcf8
unsigned int bit_ceil(unsigned int n) {
   unsigned int x = 1;
   while(x < (unsigned int)(n)) x *= 2;
   return x;
}
int countr_zero(unsigned int n) { return __builtin_ctz(n); }
constexpr int countr_zero_constexpr(unsigned int n) {
   int x = 0;
   while(!(n & (1 << x))) x++;
   return x;
}
template<class S, S (*op)(S, S), S (*e)()> struct segtree {
   public:
   segtree() : segtree(0) {}
   explicit segtree(int n) : segtree(vector<S>(n, e())) {}
   explicit segtree(const vector<S>& v) : _n(int(v.size())) {
      size = (int)bit_ceil((unsigned int)(_n));
      log = countr_zero((unsigned int)size);
      d = vector<S>(2 * size, e());
      for(int i = 0; i < _n; i++) d[size + i] = v[i];
      for(int i = size - 1; i >= 1; i--) { update(i); }
   }

   void set(int p, S x) {
      // assert(0 <= p && p < _n);
      p += size;
      d[p] = x;
      for(int i = 1; i <= log; i++) update(p >> i);
   }

   S get(int p) const {
      // assert(0 <= p && p < _n);
      return d[p + size];
   }

   S prod(int l, int r) const {
      // assert(0 <= l && l <= r && r <= _n);
      S sml = e(), smr = e();
      l += size;
      r += size;

      while(l < r) {
         if(l & 1) sml = op(sml, d[l++]);
         if(r & 1) smr = op(d[--r], smr);
         l >>= 1;
         r >>= 1;
      }
      return op(sml, smr);
   }

   S all_prod() const { return d[1]; }

   template<class F> int max_right(int l, F f) {
      // assert(0 <= l && l <= _n);
      // assert(f(e()));
      if(l == _n) return _n;
      l += size;
      S sm = e();
      do {
         while(l % 2 == 0) l >>= 1;
         if(!f(op(sm, d[l]))) {
            while(l < size) {
               l = (2 * l);
               if(f(op(sm, d[l]))) {
                  sm = op(sm, d[l]);
                  l++;
               }
            }
            return l - size;
         }
         sm = op(sm, d[l]);
         l++;
      } while((l & -l) != l);
      return _n;
   }  // faa03f

   template<class F> int min_left(int r, F f) {
      // assert(0 <= r && r <= _n);
      // assert(f(e()));
      if(r == 0) return 0;
      r += size;
      S sm = e();
      do {
         r--;
         while(r > 1 && (r % 2)) r >>= 1;
         if(!f(op(d[r], sm))) {
            while(r < size) {
               r = (2 * r + 1);
               if(f(op(d[r], sm))) {
                  sm = op(d[r], sm);
                  r--;
               }
            }
            return r + 1 - size;
         }
         sm = op(d[r], sm);
      } while((r & -r) != r);
      return 0;
   }  // efa466

   private:
   int _n, size, log;
   vector<S> d;

   void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

using ar = array<ll, 3>;
ll lcm(ll a, ll b) {
    return a * (b / __gcd(a, b));
}
ar e() { return {0, 1, 1};}
ar op(ar a, ar b) {
    ar c = {1, 1, 1};
    for(int i = 0; i < 3; i ++) {
        for(int j = 0; j + i < 3; j ++) {
            ll g = __gcd(a[i], b[j]);
            if(g) c[i + j] = lcm(c[i + j], g);
            else c[i + j] = 0;
        }
    }
    return c;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll n, m;
    cin >> n >> m;

    segtree<ar, op, e> seg(n);
    vector<ll> a(n);
    rep(i, n) {
        cin >> a[i];
        seg.set(i, {a[i], 0, 0});
    }
    rep(i, m) {
        string s;
        cin >> s;
        if(s == "U") {
            ll x, y;
            cin >> x >> y;
            x --;
            seg.set(x, {y, 0, 0});
        } else {
            ll l, r, x;
            cin >> l >> r >> x;
            l --;
            cout << seg.prod(l, r)[x] << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 490
memory_kb: 11668
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

template <typename M, typename N, M (*f)(M, M), M (*g)(M, N), M (*m1)()>
struct SegmentTree {
    int sz, n;
    vector<M> data;
    SegmentTree(int _n = 0) : n(_n) {
        sz = 1;
        while (sz < _n)
            sz <<= 1;
        data.assign(2 * sz, m1());
    }
    void run(vector<M> &v) {
        for (int i = 0; i < (int)v.size(); i++)
            data[i + sz] = v[i];
        for (int k = sz - 1; k > 0; k--)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    void set(int k, const M &x) {
        k += sz;
        data[k] = x;
        while (k >>= 1)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    void update(int k, const N &x) {
        k += sz;
        data[k] = g(data[k], x);
        while (k >>= 1)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    M query(int a, int b) {
        M L = m1(), R = m1();
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1)
                L = f(L, data[a++]);
            if (b & 1)
                R = f(data[--b], R);
        }
        return f(L, R);
    }
    M operator[](const int &k) const {
        return data[k + sz];
    }
    vector<M> get() {
        return {data.begin() + sz, data.begin() + sz + n};
    }
    template <class F> int max_right(int L, F ch) const {
        int l = sz + L, w = 1;
        M ansL = m1();
        for (; L + w <= sz; l >>= 1, w <<= 1)
            if (l & 1) {
                if (not ch(f(ansL, data[l])))
                    break;
                ansL = f(ansL, data[l++]);
                L += w;
            }
        while (l <<= 1, w >>= 1) {
            if (L + w <= sz && ch(f(ansL, data[l]))) {
                ansL = f(ansL, data[l++]);
                L += w;
            }
        }
        return L;
    }
    template <class F> int min_left(int R, F ch) const {
        int r = sz + R, w = 1;
        M ansR = m1();
        for (; R - w >= 0; r >>= 1, w <<= 1)
            if (r & 1) {
                if (not ch(f(data[r - 1], ansR)))
                    break;
                ansR = f(data[--r], ansR);
                R -= w;
            }
        while (r <<= 1, w >>= 1) {
            if (R - w >= 0 && ch(f(data[r - 1], ansR))) {
                ansR = f(data[--r], ansR);
                R -= w;
            }
        }
        return R;
    }
};

/**
 * @brief Segment Tree
 */

using TU = tuple<ll,ll,ll>;

TU f(TU A, TU B) {
    auto [a0,a1,a2] = A;
    auto [b0,b1,b2] = B;
    ll c0 = gcd(a0,b0);
    ll c1 = lcm(gcd(a0,b1), gcd(a1,b0));
    ll c2 = lcm(gcd(a0,b2), lcm(gcd(a1,b1), gcd(a2,b0)));
    return {c0,c1,c2};
}

TU g(TU A, ll B) {
    return {B,0,0};
}

TU e() {return {0,0,0};}

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    int N, Q;
    cin >> N >> Q;
    SegmentTree<TU,ll,f,g,e> Seg(N);
    rep(i,0,N) {
        ll A;
        cin >> A;
        Seg.update(i,A);
    }
    while(Q--) {
        char C;
        cin >> C;
        if (C == 'Q') {
            int L, R, K;
            cin >> L >> R >> K;
            L--;
            auto [A0, A1, A2] = Seg.query(L,R);
            if (K == 0) cout << A0 << '\n';
            if (K == 1) cout << A1 << '\n';
            if (K == 2) cout << A2 << '\n';
        }
        else {
            int P;
            ll X;
            cin >> P >> X;
            P--;
            Seg.update(P,X);
        }
    }
}
accuracy: 1
time_ms: 280
memory_kb: 9284
final_rank: 4

code_snippet: #include <numeric>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <map>
#include <array>
using array = std::array<int, 3>;
const long long INF{(long long)1e9};
long long pow(long long a, long long e) {
    if (e == INF) return 1LL;
    long long res{1};
    while (e) {
        if (e & 1) res *= a;
        a *= a;
        e >>= 1;
    }
    return res;
}
struct Item {
    int len{};
    std::map<int, array> map; 
    std::array<long long, 3> mult{ 1LL, 1LL, 1LL };
};
Item identity() {
    return Item{};
}
array merge(const array& L, const array& R) {
    array res;
    for (int i{}, j{}, k{} ; i < 3 ; i++) {
        if (L[j] < R[k]) res[i] = L[j++];
        else res[i] = R[k++];
    }
    return res;
}
Item operation(Item L, Item R) {
    for (const auto& [key, _] : L.map) {
        if (R.map.find(key) == R.map.end()) {
            array cur{INF, INF, INF};
            for (int i{} ; i < std::min(3, R.len) ; i++) cur[i] = 0;
            R.map[key] = cur;
        }
    }
    for (auto [key, arr] : R.map) {
        auto it{L.map.find(key)};
        if (it == L.map.end()) {
            array cur{INF, INF, INF};
            for (int i{} ; i < std::min(3, L.len) ; i++) cur[i] = 0;
            L.map[key] = cur;
        }
        it = L.map.find(key);
        assert(it != L.map.end());
        for (int i{} ; i < 3 ; i++)
            L.mult[i] /= pow(key, it->second[i]);
        auto merged{merge(it->second, arr)};
        assert(merged[0] <= merged[1] and merged[1] <= merged[2]);
        it->second = merged;
        for (int i{} ; i < 3 ; i++) 
            L.mult[i] *= pow(key, merged[i]);
    } 
    for (auto it{L.map.begin()} ; it != L.map.end() ; ) {
        if (it->second == array{0, 0, 0}) {
            it = L.map.erase(it);
        }
        else {
            it++;
        }
    }
    L.len += R.len;
    return L;
}
struct SegmentTree {
    int n;
    std::vector<Item> data;
    SegmentTree(const std::vector<Item>& A) : n{(int)A.size()}, data(n << 1) {
        for (int i{} ; i < n ; i++) data[n + i] = A[i];
        for (int i{n - 1} ; i ; i--) data[i] = operation(data[i << 1 | 0], data[i << 1 | 1]);
    }
    void set(int i, Item v) {
        assert(0 <= i and i < n);
        i += n;
        data[i] = v;
        for (i >>= 1 ; i ; i >>= 1) 
            data[i] = operation(data[i << 1 | 0], data[i << 1 | 1]);
    }
    Item prod(int l, int r) const {
        assert(0 <= l and l <= r and r <= n);
        Item L{identity()}, R{identity()};
        for (l += n, r += n ; l < r ; l >>= 1, r >>= 1) {
            if (l & 1) {
                L = operation(L, data[l++]);
            }
            if (r & 1) {
                R = operation(data[--r], R);
            }
        }
        return operation(L, R);
    }
};
const int MAX{1000010};
int P[MAX];
std::vector<std::pair<int, int>> factorize(int x) {
    std::vector<std::pair<int, int>> res;
    while (x > 1) {
        int d{P[x]};
        int cnt{};
        while (P[x] == d) {
            cnt++;
            assert(x % d == 0);
            x /= d;
        }
        res.push_back(std::pair{d, cnt});
    }
    return res;
}
Item generate(int x) {
    Item item{};
    item.len = 1;
    for (auto [d, k] : factorize(x)) {
        item.map[d] = array{k, INF, INF};
        item.mult[0] *= pow(d, k);
    }
    return item;
}
int main() {
    std::iota(P, P + MAX, 0);
    for (int i{2} ; i * i < MAX ; i++) if (P[i] == i) {
        for (int j{i * i} ; j < MAX ; j += i) P[j] = std::min(P[j], i);
    } 
    int N, M;
    std::cin >> N >> M;
    std::vector<Item> A(N);
    for (int i{} ; i < N ; i++) {
        int a;
        std::cin >> a;
        A[i] = generate(a);
    }
    SegmentTree seg{A};
    while (M--) {
        char c;
        std::cin >> c;
        if (c == 'U') {
            int j, x;
            std::cin >> j >> x;
            seg.set(j - 1, generate(x));
        }
        else if (c == 'Q') {
            int l, r, k;
            std::cin >> l >> r >> k;
            l--;
            Item prod{seg.prod(l, r)};
            std::cout << prod.mult[k] << '\n';
        }
        else assert(false);
    }
}
accuracy: 1
time_ms: 750
memory_kb: 102864
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0 ; i < (n) ; i++)
#define vec vector
#undef long
#define long long long
using ll = long;

template<class S, S(*op)(S, S), S(*e)()>
struct segtree {
private:
    int _n, size, log;
    vec<S> d;

    void update(int k) {
        d[k] = op(d[2 * k], d[2 * k + 1]);
    }

public:
    segtree() : segtree(0) {
    }

    segtree(int n) : segtree(vec<S>(n, e())) {
    }

    segtree(const vec<S> &v) : _n(int(v.size())) {
        log = 0;
        while ((1 << log) < _n) log++;
        size = 1 << log;
        d = vec<S>(2 * size, e());
        rep(i, _n) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) update(i);
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size, r += size;
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l /= 2, r /= 2;
        }
        return op(sml, smr);
    }
};

struct N {
    long x, y, z;
    N() { x = 0, y = 0, z = 0; }
    N(long xx, long yy, long zz) { x = xx, y = yy, z = zz; }
};

N op(N a, N b) {
    long x = gcd(a.x, b.x);
    long y = lcm(gcd(a.x, b.y), gcd(a.y, b.x));
    long z = lcm(lcm(gcd(a.x, b.z), gcd(a.y, b.y)), gcd(a.z, b.x));
    return N{x, y, z};
}

N e() { return N{0, 0, 0}; }

void solve() {
    int n, query;
    cin >> n >> query;
    vec<int> a(n);
    rep(i, n) cin >> a[i];
    vec<N> to_seg(n);
    rep(i, n) to_seg[i] = N{a[i], 0, 0};
    segtree<N, op, e> seg(to_seg);
    while (query--) {
        char c;
        cin >> c;
        if (c == 'U') {
            int idx;
            long x;
            cin >> idx >> x;
            idx--;
            seg.set(idx, N{x, 0, 0});
        } else {
            int l, r, k;
            cin >> l >> r >> k;
            l--;
            const N ans = seg.prod(l, r);
            if (k == 0) cout << ans.x << endl;
            if (k == 1) cout << ans.y << endl;
            if (k == 2) cout << ans.z << endl;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
}
accuracy: 1
time_ms: 210
memory_kb: 12112
final_rank: 2

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

using ll = long long;

template <typename Monoid>
struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) L = f(L, seg[a++]);
      if (b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

};

const ll amax = 1e6 + 100;

struct S
{
    ll len;
    ll num[3];
    
    S() = default;
    S(ll n_) 
    {
        len = 1;
        num[0] = n_;
        num[1] = num[2] = 0;
    }
    
};

S op(S a, S b)
{
    S ret;
    ret.len = a.len + b.len;
    for (int k = 0; k < 3; ++k)
    {
        if (k >= ret.len)
        {
            ret.num[k] = 0;
            continue;
        }
        ll ansk = 1;
        for (int i = 0; i <= k; ++i)
        {
            int j = k - i;
            if (i > a.len || j > b.len) continue;
            ll g = gcd(a.num[i], b.num[j]);
            ansk = lcm(g, ansk);
        }
        ret.num[k] = ansk;
    }
    return ret;
}

int main()
{
    ll N, M; cin >> N >> M;
    vector<ll> A(N);
    for (auto &a : A) cin >> a;
    
    // init of S(e)
    S e;
    {
        e.len = 0;
        e.num[0] = e.num[1] = e.num[2] = 0;
    }
    
    SegmentTree<S> seg(N, op, e);
    for (int i = 0; i < N; ++i)
    {
        ll a = A[i];
        S add(a);
        seg.set(i, add);
    }
    seg.build();
    
    while (M--)
    {
        char c; cin >> c;
        
        if (c == 'U')
        {
            ll j, x; cin >> j >> x;
            j--;
            S add(x);
            seg.update(j, add);
        }
        else if (c == 'Q')
        {
            ll l, r, k; cin >> l >> r >> k;
            l--, r--;
            r++;
            S ret = seg.query(l, r);
            cout << ret.num[k] << '\n';
        }
        
    }
    
    
    return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 12152
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
ll lcm(ll a,ll b){
    if(a+b==0)return 0;
    return a/gcd(a,b)*b;
}
ll lcm(ll a,ll b,ll c){return lcm(lcm(a,b),c);};

template<typename S>
struct segtree{
    S op(S a,S b){
        return {gcd(a[0],b[0]),
        lcm(gcd(a[0],b[1]),gcd(a[1],b[0])),
        lcm(gcd(a[0],b[2]),gcd(a[1],b[1]),gcd(a[2],b[0]))};
    }
    S e(){
        return {0,0,0};
    }

  int sz,N;
  vector<S>seg;

  segtree(int n){
    sz=1;
    N=n;
    while(sz<n)sz<<=1;
    seg.assign(2*sz,e());
  }
  void set(int k,S x){
    k+=sz;
    seg[k]=x;
    while(k>>=1){
      seg[k]=op(seg[2*k],seg[2*k+1]);
    }
  }
  S query(int a,int b){
    S L=e(),R=e();
    for(a+=sz,b+=sz;a<b;a>>=1,b>>=1){
      if(a&1)L=op(L,seg[a++]);
      if(b&1)R=op(seg[--b],R);
    }
    return op(L,R);
  }
};

int main() {
    ll N,Q,A;
    cin>>N>>Q;
    segtree<vll> S(N);
    for(int i=0;i<N;i++){
        cin>>A;
        S.set(i,{A,0,0});
    }
    while(Q--){
        char C;
        cin>>C;
        if(C=='Q'){
            ll L,R,K;
            cin>>L>>R>>K;
            vll res=S.query(L-1,R);
            cout<<res[K]<<endl;
        }
        else{
            ll x,y;
            cin>>x>>y;
            S.set(x-1,{y,0,0});
        }
    }
}
accuracy: 1
time_ms: 490
memory_kb: 17476
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
using vvvvb = vector<vvvb>;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
template<class T>
bool chmax(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p < q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

template<class T>
bool chmin(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}
const ll mod = 1e9 + 7;
ll lcm(ll a,ll b){
    if(a+b==0)return 0;
    return a/gcd(a,b)*b;
}
ll lcm(ll a,ll b,ll c){return lcm(lcm(a,b),c);};

template<typename S>
struct segtree{
    S op(S a,S b){
        S res(3);
        res[0]=gcd(a[0],b[0]);
        res[1]=lcm(gcd(a[0],b[1]),gcd(a[1],b[0]));
        res[2]=lcm(gcd(a[0],b[2]),gcd(a[1],b[1]),gcd(a[2],b[0]));
        return res;
    }
    S e(){
        S res(3,0);
        return res;
    }

  int sz,N;
  vector<S>seg;

  segtree(int n){
    // 初期化不要のとき
    sz=1;
    N=n;
    while(sz<n)sz<<=1;
    seg.assign(2*sz,e());
  }

  segtree(int n,vector<S>init){
    // 初期化が必要なとき
    sz=1;
    N=n;
    while(sz<n)sz<<=1;
    seg.assign(2*sz,e());
    for(int i=0;i<n;i++)seg[i+sz]=init[i];
    for(int k=sz-1;k>0;k--)seg[k]=op(seg[2*k],seg[2*k+1]);
  }

  void set(int k,S x){
    k+=sz;
    seg[k]=x;
    while(k>>=1){
      seg[k]=op(seg[2*k],seg[2*k+1]);
    }
  }

  S query(int a,int b){
    S L=e(),R=e();
    for(a+=sz,b+=sz;a<b;a>>=1,b>>=1){
      if(a&1)L=op(L,seg[a++]);
      if(b&1)R=op(seg[--b],R);
    }
    return op(L,R);
  }
  S get(S k){return seg[k+sz];}
};


int main() {
    ll N,Q;
    cin>>N>>Q;
    vll A(N);
    rep(i,N)cin>>A[i];
    segtree<vll> S(N);
    rep(i,N){
        vll R(3,0);
        R[0]=A[i];
        S.set(i,R);
    }
    rep(q,Q){
        char C;
        cin>>C;
        if(C=='Q'){
            ll L,R,K;
            cin>>L>>R>>K;
            auto res=S.query(L-1,R);
            cout<<res[K]<<endl;
        }
        else{
            ll x,y;
            cin>>x>>y;
            A[x-1]=y;
            vll R(3,0);
            R[0]=A[x-1];
            S.set(x-1,R);
        }
    }
}
accuracy: 1
time_ms: 480
memory_kb: 18268
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
template<int mod>istream &operator>>(istream &is,static_modint<mod> &a){long long b;is>>b;a=b;return is;}
istream &operator>>(istream &is,modint &a){long long b;cin>>b;a=b;return is;}
#endif
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) static_cast<void>(0)
#define debugg(...) static_cast<void>(0)
#define esper(...) static_cast<void>(0)
template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;}
#endif
using ll=long long;
using ull=unsigned long long;
using P=pair<ll,ll>;
template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>;
template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);}
template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);}
template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;}
template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;}
template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;}
template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;}
#define reps(i,a,n) for(int i=(a);i<(n);i++)
#define rep(i,n) reps(i,0,n)
#define all(x) x.begin(),x.end()
#define pcnt(x) __builtin_popcountll(x)
#define fin(x) return cout<<x<<'\n',static_cast<void>(0)
ll myceil(ll a,ll b){return (a+b-1)/b;}
template<typename T,size_t n,size_t id=0>
auto vec(const int (&d)[n],const T &init=T()){
  if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init));
  else return init;
}
void SOLVE();
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout<<fixed<<setprecision(16);
  #ifdef LOCAL
  clock_t start=clock();
  #endif
  int testcase=1;
  //cin>>testcase;
  for(int i=0;i<testcase;i++){
    SOLVE();
  }
  #ifdef LOCAL
  cerr<<"time:";
  cerr<<(clock()-start)/1000;
  cerr<<"ms\n";
  #endif
}
vector<ll>op(vector<ll>l,vector<ll>r){
  if(l[0]==-1)return r;
  if(r[0]==-1)return l;
  vector<ll>ret(3,1);
  rep(i,3)rep(j,3-i)ret[i+j]=lcm(ret[i+j],gcd(l[i],r[j]));
  return ret;
}
vector<ll>e(){
  vector<ll>ret(3,-1);
  return ret;
}
vector<ll>a;
struct SegTree{
  vector<vector<ll>>dat;
  SegTree(int n){
    int z=1;
    while(z<n)z<<=1;
    dat.resize(z*2,e());
    rep(i,n){
      dat[i+z][0]=a[i];
      dat[i+z][1]=dat[i+z][2]=0;
    }
    for(int i=z-1;i>=1;i--)dat[i]=op(dat[i*2],dat[i*2+1]);
  }
  void set(int i,ll x){
    i+=dat.size()>>1;
    dat[i][0]=x;
    i>>=1;
    while(i){
      dat[i]=op(dat[i*2],dat[i*2+1]);
      i>>=1;
    }
  }
  vector<ll>prod(int l,int r)const{
    l+=dat.size()>>1,r+=dat.size()>>1;
    vector<ll>ret=e();
    while(l<r){
      if(l&1)ret=op(ret,dat[l++]);
      if(r&1)ret=op(ret,dat[--r]);
      l>>=1,r>>=1;
    }
    return ret;
  }
};
void SOLVE(){
  int n,q;
  cin>>n>>q;
  a.resize(n);
  cin>>a;
  SegTree seg(n);
  while(q--){
    char c;
    cin>>c;
    if(c=='U'){
      int i;
      ll x;
      cin>>i>>x;
      i--;
      seg.set(i,x);
    }
    else{
      int l,r,k;
      cin>>l>>r>>k;
      l--;
      cout<<seg.prod(l,r)[k]<<endl;
    }
  }
}
accuracy: 1
time_ms: 360
memory_kb: 18268
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(ll i = 0; i < n; i++)
#define all(a) (a).begin(),(a).end()

using S = array<ll,3>;
S e = {-1,-1,-1};
const int max_n = 400010;
S seg[2 * max_n];
int N;
void init(int n){
    N = 1;
    while(N < n)N*=2;
    rep(i,2*N){
        seg[i] = e;
    }
}

ll gcd(ll a,ll b){
    if(a == -1)return b;
    if(b == -1)return a;
    if(b == 0)return a;
    return gcd(b, a % b);
}

ll lcm(ll a,ll b){
    if(a == -1)return b;
    if(b == -1)return a;
    return a / gcd(a,b) * b;
}

S f(S a,S b){
    if(a == e)return b;
    if(b == e)return a;
    S nw;
    nw[0] = gcd(a[0],b[0]);
    nw[1] = gcd(lcm(a[0],b[0]), gcd(a[1],b[1]));
    nw[2] = gcd(lcm(lcm(a[0],b[0]), gcd(a[1],b[1])),gcd(a[2],b[2]));

    if(a[1] == -1 && b[1] == -1){
        nw[2] = -1;
    }
    
    return nw;
}

void update(int index, S x){
    index += N-1;
    seg[index] = x;
    while(index > 0){
        index = (index - 1)/2;
        seg[index] = f(seg[index*2 + 1], seg[index*2 + 2]);
    }
}

S query(int a,int b,int index,int l,int r){
    if(a>= r || b <= l)return e;
    if(a <= l && b >= r) return seg[index];
    S v1 = query(a,b,2*index+1,l, (l + r)/2);
    S v2 = query(a,b,index*2+2,(l + r)/2, r);
    return f(v1,v2);
}
S query(int l,int r){
    return query(l,r,0,0,N);
}

int main(){
    ll n,m;
    cin >> n >> m;
    vector<ll> x(n);
    rep(i,n) cin >> x[i];
    init(n);
    rep(i,n){
        update(i, {x[i],-1,-1});
    }
    rep(i,m){
        char t;
        cin >> t;
        if(t == 'Q'){
            int l,r,k;
            cin >> l >> r >> k;
            cout << query(l-1,r)[k] << endl;
        }else{
            int ind,nx;
            cin >> ind >> nx;
            update(ind-1, {nx,-1,-1});
        }
    }
}
accuracy: 1
time_ms: 370
memory_kb: 12160
final_rank: 8

code_snippet: #include <bits/stdc++.h>

#define rep(i,s,n) for(int i = int(s); i < int(n); i++)
#define rrep(i,s,n) for(int i = int(n) - 1; i >= int(s); i--)
#define all(v) (v).begin(), (v).end()

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template<class T>
bool chmin(T &a, T b) {
    if(a <= b) return false;
    a = b;
    return true;
}

template<class T>
bool chmax(T &a, T b) {
    if(a >= b) return false;
    a = b;
    return true;
}

using namespace std;


template<class S, S (*op)(S, S), S (*e)()> struct segtree {
    int n, sz;
    vector<S> data;
    void update(int i){
        data[i] = op(data[2*i],data[2*i+1]);
    }
    segtree(int n) : segtree(vector<S>(n,e())) {}
    segtree (const vector<S> &v) : n(int(v.size())), sz(1) {
        while (sz < n) sz <<= 1;
        data = vector<S>(2*sz,e());
        rep(i,0,n) data[sz+i] = v[i];
        rrep(i,1,sz) update(i);
    }
    void set(int p, S x){
        assert(0 <= p && p < n);
        p += sz;
        data[p] = x;
        while (p > 1){
            p >>= 1;
            update(p);
        }
    }
    S get(int p){
        return data[p+sz];
    }
    S prod(int l, int r){
        assert(0 <= l && l <= r && r <= n);
        S sml = e(), smr = e();
        l += sz, r += sz;
        while (l < r){
            if (l & 1) sml = op(sml,data[l++]);
            if (r & 1) smr = op(data[--r],smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml,smr);
    }
};

const int mx = 1000100;
using ar = array<int,4>;

struct S {
    vector<ar> vec;
    int len;
};

void say(ar a){
    cerr << a[0] << " : " << a[1] << a[2] << a[3] << endl;
}

ar merge(ar a, ar b){
    assert(a[0] == b[0]);
    ar c = a;
    int ia = 1, ib = 1;
    rep(i,0,3){
        if (a[ia] < b[ib]){
            c[1+i] = a[ia++];
        }
        else {
            c[1+i] = b[ib++];
        }
    }
    //cerr << "merge" << endl; say(a); say(b); say(c);
    return c;
}
ar merge(ar a, int len){
    if (len >= 3){
        a[1] = a[2] = a[3] = 0;
    }
    else if (len == 2){
        a[3] = a[1];
        a[1] = a[2] = 0;
    }
    else if (len == 1){
        a[3] = a[2];
        a[2] = a[1];
        a[1] = 0;
    }
    return a;
}

S op(S a, S b){
    int ia = 0, ib = 0;
    int sa = a.vec.size(), sb = b.vec.size();
    S c;
    c.len = a.len + b.len;
    while (ia < sa || ib < sb){
        if (ib == sb){
            if (b.len >= 3) break;
            auto add = merge(a.vec[ia++],b.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            continue;
        }
        if (ia == sa){
            if (a.len >= 3) break;
            auto add = merge(b.vec[ib++],a.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            continue;
        }
        if (a.vec[ia][0] == b.vec[ib][0]){
            auto add = merge(a.vec[ia],b.vec[ib]);
            if (add[3] > 0) c.vec.emplace_back(add);
            ia++, ib++;
        }
        else if (a.vec[ia][0] < b.vec[ib][0]){
            auto add = merge(a.vec[ia],b.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            ia++;
        }
        else {
            auto add = merge(b.vec[ib],a.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            ib++;
        }
    }
    return c;
}

S e(){
    return S();
}

const int iinf = 1e8;

random_device rd;
mt19937_64 mt(rd());

int rnd(int l, int r){
    return mt() % (r-l+1) + l;
}

int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int n, q; cin >> n >> q;
    vector<int> sieve(mx,1);
    for (int p = 2; p < mx; p++){
        if (sieve[p] != 1) continue;
        for (int q = p; q < mx; q += p){
            sieve[q] = p;
        }
    }
    auto fact = [&](int x){
        vector<ar> res;
        while (x > 1){
            int p = sieve[x];
            int e = 0;
            while (x % p == 0){
                x /= p;
                e++;
            }
            res.emplace_back(ar{p,e,iinf,iinf});
        }
        reverse(all(res));
        return res;
    };
    auto powll = [&](ll p, int e){
        ll res = 1;
        while (e > 0){
            if (e & 1) res *= p;
            p *= p;
            e >>= 1;
        }
        return res;
    };
    vector<int> a(n);
    rep(i,0,n){
        cin >> a[i];
    }
    segtree<S,op,e> seg([&]{
        vector<S> s(n);
        rep(i,0,n){
            s[i].len = 1;
            s[i].vec = fact(a[i]);
        }
        return s;
    }());
    while (q--){
        char t; cin >> t;
        if (t == 'Q'){
            int l, r, k; cin >> l >> r >> k; l--;
            auto vec = seg.prod(l,r).vec;
            ll ans = 1;
            for (auto pe : vec){
                ans *= powll(pe[0],pe[k+1]);
            }
            cout << ans << '\n';
        }
        else {
            int i, x; cin >> i >> x; i--;
            S s;
            s.len = 1;
            s.vec = fact(x);
            seg.set(i,s);
        }
    }
}
accuracy: 1
time_ms: 230
memory_kb: 43736
final_rank: 10

code_snippet: #include <bits/stdc++.h>

#define rep(i,s,n) for(int i = int(s); i < int(n); i++)
#define rrep(i,s,n) for(int i = int(n) - 1; i >= int(s); i--)
#define all(v) (v).begin(), (v).end()

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template<class T>
bool chmin(T &a, T b) {
    if(a <= b) return false;
    a = b;
    return true;
}

template<class T>
bool chmax(T &a, T b) {
    if(a >= b) return false;
    a = b;
    return true;
}

using namespace std;


template<class S, S (*op)(S, S), S (*e)()> struct segtree {
    int n, sz;
    vector<S> data;
    void update(int i){
        data[i] = op(data[2*i],data[2*i+1]);
    }
    segtree(int n) : segtree(vector<S>(n,e())) {}
    segtree (const vector<S> &v) : n(int(v.size())), sz(1) {
        while (sz < n) sz <<= 1;
        data = vector<S>(2*sz,e());
        rep(i,0,n) data[sz+i] = v[i];
        rrep(i,1,sz) update(i);
    }
    void set(int p, S x){
        assert(0 <= p && p < n);
        p += sz;
        data[p] = x;
        while (p > 1){
            p >>= 1;
            update(p);
        }
    }
    S get(int p){
        return data[p+sz];
    }
    S prod(int l, int r){
        assert(0 <= l && l <= r && r <= n);
        S sml = e(), smr = e();
        l += sz, r += sz;
        while (l < r){
            if (l & 1) sml = op(sml,data[l++]);
            if (r & 1) smr = op(data[--r],smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml,smr);
    }
};

const int mx = 1000100;
using ar = array<int,4>;

struct S {
    vector<ar> vec;
    int len;
};

void say(ar a){
    cerr << a[0] << " : " << a[1] << a[2] << a[3] << endl;
}

ar merge(ar a, ar b){
    assert(a[0] == b[0]);
    ar c = a;
    int ia = 1, ib = 1;
    rep(i,0,3){
        if (a[ia] < b[ib]){
            c[1+i] = a[ia++];
        }
        else {
            c[1+i] = b[ib++];
        }
    }
    //cerr << "merge" << endl; say(a); say(b); say(c);
    return c;
}
ar merge(ar a, int len){
    if (len >= 3){
        a[1] = a[2] = a[3] = 0;
    }
    else if (len == 2){
        a[3] = a[1];
        a[1] = a[2] = 0;
    }
    else if (len == 1){
        a[3] = a[2];
        a[2] = a[1];
        a[1] = 0;
    }
    return a;
}

S op(S a, S b){
    int ia = 0, ib = 0;
    int sa = a.vec.size(), sb = b.vec.size();
    S c;
    c.len = a.len + b.len;
    while (ia < sa || ib < sb){
        if (ib == sb){
            if (b.len >= 3) break;
            auto add = merge(a.vec[ia++],b.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            continue;
        }
        if (ia == sa){
            if (a.len >= 3) break;
            auto add = merge(b.vec[ib++],a.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            continue;
        }
        if (a.vec[ia][0] == b.vec[ib][0]){
            auto add = merge(a.vec[ia],b.vec[ib]);
            if (add[3] > 0) c.vec.emplace_back(add);
            ia++, ib++;
        }
        else if (a.vec[ia][0] < b.vec[ib][0]){
            auto add = merge(a.vec[ia],b.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            ia++;
        }
        else {
            auto add = merge(b.vec[ib],a.len);
            if (add[3] > 0) c.vec.emplace_back(add);
            ib++;
        }
    }
    return c;
}

S e(){
    return S();
}

const int iinf = 1e8;

random_device rd;
mt19937_64 mt(rd());

int rnd(int l, int r){
    return mt() % (r-l+1) + l;
}

int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int n, q; cin >> n >> q;
    vector<int> sieve(mx,1);
    for (int p = 2; p < mx; p++){
        if (sieve[p] != 1) continue;
        for (int q = p; q < mx; q += p){
            sieve[q] = p;
        }
    }
    auto fact = [&](int x){
        vector<ar> res;
        while (x > 1){
            int p = sieve[x];
            int e = 0;
            while (x % p == 0){
                x /= p;
                e++;
            }
            res.emplace_back(ar{p,e,9,9});
        }
        reverse(all(res));
        return res;
    };
    auto powll = [&](ll p, int e){
        ll res = 1;
        while (e > 0){
            if (e & 1) res *= p;
            p *= p;
            e >>= 1;
        }
        return res;
    };
    vector<int> a(n);
    rep(i,0,n){
        cin >> a[i];
    }
    segtree<S,op,e> seg([&]{
        vector<S> s(n);
        rep(i,0,n){
            s[i].len = 1;
            s[i].vec = fact(a[i]);
        }
        return s;
    }());
    while (q--){
        char t; cin >> t;
        if (t == 'Q'){
            int l, r, k; cin >> l >> r >> k; l--;
            auto vec = seg.prod(l,r).vec;
            ll ans = 1;
            for (auto pe : vec){
                ans *= powll(pe[0],pe[k+1]);
            }
            cout << ans << '\n';
        }
        else {
            int i, x; cin >> i >> x; i--;
            S s;
            s.len = 1;
            s.vec = fact(x);
            seg.set(i,s);
        }
    }
}
accuracy: 0.10714285714285714
time_ms: 110
memory_kb: 38560
final_rank: 17