// 0<=l<=r<=N ? // l(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter) { let n = sc.next::(); let q = sc.next::(); let mut map = std::collections::BTreeMap::new(); let mut seg = LazySegmentTree::build((0..n).map(|_| (0, 1)), n, R); for i in 0..n { let a = sc.next::(); map.insert(i, (i + 1, a)); seg.update(i, i + 1, a); } for _ in 0..q { let op = sc.next::(); let l = sc.next::(); let r = sc.next::(); if op == 0 { writeln!(out, "{}", seg.find(l, r).0).ok(); } else if op == 1 { let v = sc.next::(); if l == r { continue; } for &x in [l, r].iter() { if let Some((&s, &(t, a))) = map.range(..x).next_back() { if t > x { map.remove(&s); map.insert(s, (x, a)); map.insert(x, (t, a)); } } } while let Some((&s, _)) = map.range(l..r).next() { map.remove(&s); } map.insert(l, (r, v)); seg.update(l, r, v); } else { for &x in [l, r].iter() { if let Some((&s, &(t, a))) = map.range(..x).next_back() { if t > x { map.remove(&s); map.insert(s, (x, a)); map.insert(x, (t, a)); } } } let mut memo = vec![]; while let Some((&s, &(t, a))) = map.range(l..r).next() { map.remove(&s); let na = (a as f64).sqrt().floor() as i64; seg.update(s, t, na); if na > 1 { memo.push((s, t, na)); } } for (s, t, v) in memo { map.insert(s, (t, v)); } } } } struct R; impl TE for R { type T = (i64, i64); type E = i64; fn fold(&self, l: &Self::T, r: &Self::T) -> Self::T { (l.0 + r.0, l.1 + r.1) } fn eval(&self, x: &Self::T, f: &Self::E) -> Self::T { if *f == -1 { *x } else { (*f * x.1, x.1) } } fn merge(&self, g: &Self::E, h: &Self::E) -> Self::E { if *h == -1 { *g } else { *h } } fn e(&self) -> Self::T { (0, 0) } fn id(&self) -> Self::E { -1 } } // ---------- begin scannner ---------- #[allow(dead_code)] mod scanner { use std::str::FromStr; pub struct Scanner<'a> { it: std::str::SplitWhitespace<'a>, } impl<'a> Scanner<'a> { pub fn new(s: &'a String) -> Scanner<'a> { Scanner { it: s.split_whitespace(), } } pub fn next(&mut self) -> T { self.it.next().unwrap().parse::().ok().unwrap() } pub fn next_bytes(&mut self) -> Vec { self.it.next().unwrap().bytes().collect() } pub fn next_chars(&mut self) -> Vec { self.it.next().unwrap().chars().collect() } pub fn next_vec(&mut self, len: usize) -> Vec { (0..len).map(|_| self.next()).collect() } } } // ---------- end scannner ---------- use std::io::Write; use std::collections::*; type Map = BTreeMap; type Set = BTreeSet; type Deque = VecDeque; fn main() { use std::io::Read; let mut s = String::new(); std::io::stdin().read_to_string(&mut s).unwrap(); let mut sc = scanner::Scanner::new(&s); let out = std::io::stdout(); let mut out = std::io::BufWriter::new(out.lock()); run(&mut sc, &mut out); } // ---------- begin Lazy Segment Tree ---------- pub trait TE { type T: Clone; type E: Clone; fn fold(&self, l: &Self::T, r: &Self::T) -> Self::T; fn eval(&self, x: &Self::T, f: &Self::E) -> Self::T; fn merge(&self, g: &Self::E, h: &Self::E) -> Self::E; fn e(&self) -> Self::T; fn id(&self) -> Self::E; } pub struct LazySegmentTree { n: usize, size: usize, bit: u32, op: R, data: Vec<(R::T, R::E)>, } impl LazySegmentTree { pub fn new(n: usize, op: R) -> Self { assert!(n > 0); let size = n.next_power_of_two(); let bit = size.trailing_zeros(); let data = vec![(op.e(), op.id()); 2 * size]; Self { n, size, bit, op, data, } } pub fn build(init: I, n: usize, op: R) -> Self where I: Iterator, { let mut seg = Self::new(n, op); for (data, ini) in seg.data[seg.size..].iter_mut().zip(init) { data.0 = ini; } for i in (1..seg.size).rev() { seg.pull(i); } seg } pub fn update(&mut self, l: usize, r: usize, f: R::E) { assert!(l <= r && r <= self.n); if l == r { return; } self.push_range(l, r); let mut s = l + self.size; let mut t = r + self.size; while s < t { if s & 1 == 1 { self.apply(s, &f); s += 1; } if t & 1 == 1 { t -= 1; self.apply(t, &f); } s >>= 1; t >>= 1; } let l = l + self.size; let r = r + self.size; for k in 1..=self.bit { if (l >> k) << k != l { self.pull(l >> k); } if (r >> k) << k != r { self.pull((r - 1) >> k); } } } pub fn find(&mut self, l: usize, r: usize) -> R::T { assert!(l <= r && r <= self.n); if l == r { return self.op.e(); } self.push_range(l, r); let mut l = l + self.size; let mut r = r + self.size; let mut p = self.op.e(); let mut q = self.op.e(); while l < r { if l & 1 == 1 { p = self.op.fold(&p, &self.data[l].0); l += 1; } if r & 1 == 1 { r -= 1; q = self.op.fold(&self.data[r].0, &q); } l >>= 1; r >>= 1; } self.op.fold(&p, &q) } pub fn set_at(&mut self, x: usize, v: R::T) { assert!(x < self.n); let x = x + self.size; for k in (1..=self.bit).rev() { self.push(x >> k); } self.data[x].0 = v; for k in 1..=self.bit { self.pull(x >> k); } } pub fn max_right

(&mut self, l: usize, f: P) -> usize where P: Fn(&R::T) -> bool, { assert!(l <= self.n); assert!(f(&self.op.e())); if l == self.n { return self.n; } self.push_range(l, self.n); let mut l = l + self.size; let mut sum = self.op.e(); while { l >>= l.trailing_zeros(); let v = self.op.fold(&sum, &self.data[l].0); if !f(&v) { while l < self.size { self.push(l); l <<= 1; let v = self.op.fold(&sum, &self.data[l].0); if f(&v) { sum = v; l += 1; } } return l - self.size; } sum = v; l += 1; l.count_ones() > 1 } {} self.n } pub fn min_left

(&mut self, r: usize, f: P) -> usize where P: Fn(&R::T) -> bool, { assert!(r <= self.n); assert!(f(&self.op.e())); if r == 0 { return 0; } self.push_range(0, r); let mut r = r + self.size; let mut sum = self.op.e(); while { r -= 1; while r > 1 && r & 1 == 1 { r >>= 1; } let v = self.op.fold(&self.data[r].0, &sum); if !f(&v) { while r < self.size { self.push(r); r = 2 * r + 1; let v = self.op.fold(&self.data[r].0, &sum); if f(&v) { sum = v; r -= 1; } } return r + 1 - self.size; } sum = v; (r & (!r + 1)) != r } {} 0 } fn push_range(&mut self, l: usize, r: usize) { let l = l + self.size; let r = r + self.size; for k in (1..(self.bit + 1)).rev() { if (l >> k) << k != l { self.push(l >> k); } if (r >> k) << k != r { self.push((r - 1) >> k); } } } fn apply(&mut self, x: usize, f: &R::E) { self.data[x].0 = self.op.eval(&self.data[x].0, f); self.data[x].1 = self.op.merge(&self.data[x].1, f); } fn push(&mut self, x: usize) { let f = std::mem::replace(&mut self.data[x].1, self.op.id()); self.apply(2 * x, &f); self.apply(2 * x + 1, &f); } fn pull(&mut self, x: usize) { self.data[x].0 = self.op.fold(&self.data[2 * x].0, &self.data[2 * x + 1].0); } } // ---------- end Lazy Segment Tree ----------