// https://atcoder.jp/contests/abc256/submissions/32369947 #include #include #include #include using namespace std; #include "atcoder/lazysegtree.hpp" using ll = long long; using pl = pair; pl ti() { return {0, 0}; } ll ei() { return -1; } pl f(pl a, pl b) { return pl{a.first + b.first, a.second + b.second}; } pl g(ll b, pl a) { return b == ei() ? a : pl{a.second * b, a.second}; } ll h(ll b, ll a) { return b == ei() ? a : b; } using segtree = atcoder::lazy_segtree; struct interval_manager { using T = int; map st; interval_manager() = default; using const_iterator = typename map::const_iterator; const_iterator begin() const { return st.begin(); } const_iterator end() const { return st.end(); } const_iterator lower_bound(T x) const { auto it = st.lower_bound(x); if (it == st.begin() || prev(it)->second <= x) return it; return prev(it); } const_iterator erase(const_iterator it) { return st.erase(it); } void erase(T l, T r) { auto L = st.upper_bound(l), R = st.upper_bound(r); if (L != st.begin() && l <= prev(L)->second) --L; if (L == R) return; T nl = min(l, L->first), nr = max(r, prev(R)->second); st.erase(L, R); if (nl < l) st[nl] = l; if (r < nr) st[r] = nr; } }; int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int N, Q; cin >> N >> Q; vector a(N); for (auto& x : a) cin >> x; segtree seg(N); interval_manager m; // i に切れ目を入れる auto cut = [&](int i) { auto it = m.lower_bound(i); if (it == end(m)) return; auto [x, y] = *it; if (x < i and i < y) { m.erase(it); m.st[x] = i; m.st[i] = y; } }; for (int i = 0; i < N; i++) { seg.set(i, {a[i], 1}); m.st[i] = i + 1; } for (int i = 0; i < Q; i++) { int cmd, L, R, x = -1; cin >> cmd >> L >> R; // --L; if (cmd == 2) { // cin >> x; cut(L), cut(R); for (auto it = m.lower_bound(L); it != end(m);) { auto [l, r] = *it; if (R <= l) break; assert(L <= l and r <= R); int n = seg.get(l).first; n = sqrtl(n); seg.apply(l, r, n); if (n <= 1) { it = m.erase(it); } else { it++; } } } else if (cmd == 1) { cin >> x; m.erase(L, R); m.st[L] = R; seg.apply(L, R, x); } else { cout << seg.prod(L, R).first << "\n"; } //for (int j = 0; j < N; j++) cerr << seg.get(j).first << ","; //cerr << "sum:" << seg.prod(0, N).first << endl; } }