use std::io::{self, Read}; fn isqrt(x: u64) -> u64 { let mut r = (x as f64).sqrt() as u64; while (r + 1) * (r + 1) <= x { r += 1; } while r * r > x { r -= 1; } r } fn push(values: &mut [u64], lazy: &mut [Option], starts: &[usize], ends: &[usize], b: usize) { if let Some(x) = lazy[b] { for v in &mut values[starts[b]..ends[b]] { *v = x; } lazy[b] = None; } } fn rebuild( values: &[u64], lazy: &mut [Option], sum: &mut [u64], max_value: &mut [u64], starts: &[usize], ends: &[usize], b: usize, ) { let mut s = 0_u64; let mut mx = 0_u64; let mut mn = u64::MAX; for &v in &values[starts[b]..ends[b]] { s += v; mx = mx.max(v); mn = mn.min(v); } sum[b] = s; max_value[b] = mx; lazy[b] = if mn == mx { Some(mx) } else { None }; } fn apply_set( lazy: &mut [Option], sum: &mut [u64], max_value: &mut [u64], starts: &[usize], ends: &[usize], b: usize, x: u64, ) { lazy[b] = Some(x); sum[b] = x * (ends[b] - starts[b]) as u64; max_value[b] = x; } fn apply_sqrt_block( values: &mut [u64], lazy: &mut [Option], sum: &mut [u64], max_value: &mut [u64], starts: &[usize], ends: &[usize], b: usize, ) { if max_value[b] <= 1 { return; } if let Some(x) = lazy[b] { let y = isqrt(x); apply_set(lazy, sum, max_value, starts, ends, b, y); return; } for v in &mut values[starts[b]..ends[b]] { *v = isqrt(*v); } rebuild(values, lazy, sum, max_value, starts, ends, b); } fn main() { let mut input = String::new(); io::stdin().read_to_string(&mut input).unwrap(); let mut it = input.split_whitespace(); let n: usize = it.next().unwrap().parse().unwrap(); let q: usize = it.next().unwrap().parse().unwrap(); let block_size = 700_usize; let block_count = (n + block_size - 1) / block_size; let mut starts = vec![0_usize; block_count]; let mut ends = vec![0_usize; block_count]; for b in 0..block_count { starts[b] = b * block_size; ends[b] = ((b + 1) * block_size).min(n); } let mut values = vec![0_u64; n]; for v in &mut values { *v = it.next().unwrap().parse().unwrap(); } let mut lazy = vec![None; block_count]; let mut sum = vec![0_u64; block_count]; let mut max_value = vec![0_u64; block_count]; for b in 0..block_count { rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, b); } let mut out = String::new(); for _ in 0..q { let ty: usize = it.next().unwrap().parse().unwrap(); let l: usize = it.next().unwrap().parse().unwrap(); let r: usize = it.next().unwrap().parse().unwrap(); if l == r { if ty == 1 { let _: u64 = it.next().unwrap().parse().unwrap(); } else if ty == 0 { out.push_str("0\n"); } continue; } let lb = l / block_size; let rb = (r - 1) / block_size; match ty { 0 => { let mut ans = 0_u64; if lb == rb { if let Some(x) = lazy[lb] { ans = x * (r - l) as u64; } else { ans = values[l..r].iter().sum(); } } else { push(&mut values, &mut lazy, &starts, &ends, lb); ans += values[l..ends[lb]].iter().sum::(); rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, lb); push(&mut values, &mut lazy, &starts, &ends, rb); ans += values[starts[rb]..r].iter().sum::(); rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, rb); for b in lb + 1..rb { ans += sum[b]; } } out.push_str(&format!("{}\n", ans)); } 1 => { let x: u64 = it.next().unwrap().parse().unwrap(); if lb == rb { push(&mut values, &mut lazy, &starts, &ends, lb); values[l..r].fill(x); rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, lb); } else { push(&mut values, &mut lazy, &starts, &ends, lb); values[l..ends[lb]].fill(x); rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, lb); push(&mut values, &mut lazy, &starts, &ends, rb); values[starts[rb]..r].fill(x); rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, rb); for b in lb + 1..rb { apply_set(&mut lazy, &mut sum, &mut max_value, &starts, &ends, b, x); } } } 2 => { if lb == rb { push(&mut values, &mut lazy, &starts, &ends, lb); for v in &mut values[l..r] { *v = isqrt(*v); } rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, lb); } else { push(&mut values, &mut lazy, &starts, &ends, lb); for v in &mut values[l..ends[lb]] { *v = isqrt(*v); } rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, lb); push(&mut values, &mut lazy, &starts, &ends, rb); for v in &mut values[starts[rb]..r] { *v = isqrt(*v); } rebuild(&values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, rb); for b in lb + 1..rb { apply_sqrt_block( &mut values, &mut lazy, &mut sum, &mut max_value, &starts, &ends, b, ); } } } _ => unreachable!(), } } print!("{}", out); }