//---------- begin SegmentTree Point update Range query ---------- mod segment_tree { pub struct PURQ T> { n: usize, a: Vec, id: T, op: F, } #[allow(dead_code)] impl T> PURQ { pub fn new(n: usize, id: T, op: F) -> PURQ { let mut k = 1; while k < n { k *= 2; } PURQ { n: k, a: vec![id.clone(); 2 * k], id: id, op: op, } } pub fn update(&mut self, x: usize, v: T) { let mut k = self.n + x; let a = &mut self.a; a[k] = v; k >>= 1; while k > 0 { a[k] = (self.op)(a[2 * k].clone(), a[2 * k + 1].clone()); k >>= 1; } } pub fn update_tmp(&mut self, x: usize, v: T) { self.a[x + self.n] = v; } pub fn update_all(&mut self) { for k in (1..(self.n)).rev() { self.a[k] = (self.op)(self.a[2 * k].clone(), self.a[2 * k + 1].clone()); } } pub fn find(&self, mut l: usize, mut r: usize) -> T { let mut p = self.id.clone(); let mut q = self.id.clone(); l += self.n; r += self.n; while l < r { if (l & 1) == 1 { p = (self.op)(p, self.a[l].clone()); l += 1; } if (r & 1) == 1 { r -= 1; q = (self.op)(self.a[r].clone(), q); } l >>= 1; r >>= 1; } (self.op)(p, q) } } } //---------- end SegmentTree Point update Range query ---------- use std::io::Read; use std::io::Write; fn run() { let out = std::io::stdout(); let mut out = std::io::BufWriter::new(out.lock()); let mut s = String::new(); std::io::stdin().read_to_string(&mut s).unwrap(); let mut it = s.trim().split_whitespace(); let n: usize = it.next().unwrap().parse().unwrap(); let q: usize = it.next().unwrap().parse().unwrap(); let a: Vec = (0..n).map(|_| it.next().unwrap().parse().unwrap()).collect(); let ask: Vec<(usize, usize)> = (0..q).map(|_| { let l: usize = it.next().unwrap().parse::().unwrap() - 1; let r: usize = it.next().unwrap().parse::().unwrap(); (l, r) }).collect(); let mut left = vec![-1_000_000_000 - 1; q]; let mut right = vec![1_000_000_000; q]; loop { let mut op = vec![]; let mut update = false; for i in 0..q { if left[i] + 1 < right[i] { let m = (left[i] + right[i]) / 2; op.push((m, 1, i)); update = true; } } if !update { break; } for i in 0..n { op.push((a[i], 0, i)); } op.sort(); let mut s = segment_tree::PURQ::new(n, 0, |a, b| a + b); for &(a, op, k) in &op { if op == 0 { s.update(k, 1); } else { let v = s.find(ask[k].0, ask[k].1); if 2 * v < ask[k].1 - ask[k].0 { left[k] = a; } else { right[k] = a; } } } } let mut sum = a.clone(); sum.push(0); for i in (0..n).rev() { sum[i] += sum[i + 1]; } let mut s = segment_tree::PURQ::new(n, (0i64, 0i64), |a, b| (a.0 + b.0, a.1 + b.1)); let mut op = vec![]; for i in 0..q { op.push((right[i], 1, i)); } for i in 0..n { op.push((a[i], 0, i)); } op.sort(); let mut ans = vec![0; q]; for (v, op, k) in op { if op == 0 { s.update(k, (v, 1)); } else { let (l, r) = ask[k]; let u = s.find(l, r); ans[k] = (sum[l] - sum[r] - u.0 - ((r - l) as i64 - u.1) * v) + (u.1 * v - u.0); } } for v in ans { writeln!(out, "{}", v).ok(); } } fn main() { run(); }