#[allow(unused_imports)] use std::{ cell::RefCell, convert::{Infallible, TryFrom, TryInto as _}, fmt::{self, Debug, Display, Formatter,}, fs::{File}, hash::{Hash, Hasher}, iter::{Product, Sum}, marker::PhantomData, ops::{Add, AddAssign, Sub, SubAssign, Div, DivAssign, Mul, MulAssign, Neg, }, str::FromStr, sync::{atomic::{self, AtomicU32, AtomicU64}, Once}, collections::{*}, mem::{swap}, cmp::{self, Reverse, Ordering, Eq, PartialEq, PartialOrd}, thread::LocalKey, f64::consts::PI, time::Instant, io::{self, stdin, Read, read_to_string, BufWriter, BufReader, stdout, Write}, }; #[allow(unused_imports)] use proconio::{input, input_interactive, marker::{*}}; #[allow(unused_imports)] //use rand::{thread_rng, Rng, seq::SliceRandom}; #[allow(unused_imports)] //use ac_library::{*}; #[allow(dead_code)] const INF: i64 = 1<<60; #[allow(dead_code)] const MOD: i64 = 998244353; #[allow(dead_code)] const D: [(usize, usize); 4] = [(1, 0), (0, 1), (!0, 0), (0, !0)]; pub fn bit_length(x: usize)->usize{ 64-x.saturating_sub(1).leading_zeros()as usize } pub trait SegtreeMonoid{ type S: Clone+BeatsFail; fn identity()->Self::S; fn op(a: &Self::S, b: &Self::S)->Self::S; } pub trait LazySegtreeMonoid{ type M: SegtreeMonoid; type F: Clone; fn id_e()->::S{::identity()} fn op(a: &::S, b: &::S)->::S{::op(a, b)} fn identity()->Self::F; fn map(f: &Self::F, x: &::S)->::S; fn composition(f: &Self::F, g: &Self::F)->Self::F; } pub trait BeatsFail{ fn fail(&self) -> bool; } pub struct LazySegtree where F: LazySegtreeMonoid{ n: usize, log: usize, data: Vec<::S>, lazy: Vec, } impl LazySegtree{ // 初期値開始 pub fn new(n: usize)->Self{ let n = n.next_power_of_two(); let log = bit_length(n); let lazy = vec![F::identity(); n<<1]; let data = vec![F::id_e(); n<<1]; LazySegtree{ n, log, data, lazy, } } // vectorを飲ませるならこっち。O(N)で初期化。 pub fn build(vec: &Vec<::S>)->Self { let n = vec.len().next_power_of_two(); let log = bit_length(n); let lazy = vec![F::identity(); n<<1]; let mut data = vec![F::id_e(); n<<1]; data[n..(n+vec.len())].clone_from_slice(vec); let mut res = LazySegtree{ n, log, data, lazy, }; for i in (1..n).rev(){ res.update(i); } res } pub fn set(&mut self, mut p: usize, x: ::S){ p += self.n; for i in (1..=self.log).rev(){ self.push(p>>i); } self.data[p] = x; for i in 1..=self.log{ self.update(p>>i); } } // 下からデータ更新 #[inline(always)] fn update(&mut self, k: usize){ self.data[k] = F::op(&self.data[2*k], &self.data[2*k+1]); } // 遅延反映 #[inline(always)] fn inner_apply(&mut self, k: usize, f: F::F){ self.data[k] = F::map(&f, &self.data[k]); if k < self.n{ self.lazy[k] = F::composition(&f, &self.lazy[k]); if self.data[k].fail(){ self.push(k); self.update(k); } } } // 上から遅延更新 #[inline(always)] fn push(&mut self, k: usize){ self.inner_apply(2*k, self.lazy[k].clone()); self.inner_apply(2*k+1, self.lazy[k].clone()); self.lazy[k] = F::identity(); } pub fn get(&mut self, mut p: usize)->::S{ p += self.n; for i in (1..self.log).rev(){ self.push(p>>i); } self.data[p].clone() } // whileで打ち切った方が早そうだけどどうなんでしょう? #[inline] pub fn prod(&mut self, mut l: usize, mut r: usize)->::S{ if r<=l{return F::id_e()} l += self.n; r += self.n; for i in (1..=self.log).rev(){ if ((l>>i)<>i); } if ((r>>i)<>i); } } let mut acl = F::id_e(); let mut acr = F::id_e(); while l < r{ if l&1 != 0{ acl = F::op(&acl, &self.data[l]); l += 1; } if r&1 != 0{ r -= 1; acr = F::op(&self.data[r], &acr); } l >>= 1; r >>= 1; } F::op(&acl, &acr) } pub fn all_prod(&mut self)->::S{ self.update(1); self.data[1].clone() } pub fn apply_range(&mut self, mut l: usize, mut r: usize, f: F::F){ if l>=r{return;} l += self.n; r += self.n; for i in (1..=self.log).rev(){ if ((l>>i)<>i); } if ((r>>i)<>i); } } let left = l; let right = r; while l < r{ if l&1!=0{ self.inner_apply(l, f.clone()); l += 1; } if r&1!=0{ r -= 1; self.inner_apply(r, f.clone()); } l >>= 1; r>>=1; } for i in 1..=self.log{ if ((left>>i)<>i); } if ((right>>i)<>i); } } } pub fn max_right(&mut self, mut l: usize, g: G)->usize where G: Fn(::S)->bool{ assert!(g(F::id_e())); if l >= self.n{return self.n} l += self.n; for i in 1..=self.log{ self.push(l>>i); } let mut ac = F::id_e(); while { while l%2==0{ l>>=1; } if !g(F::op(&ac, &self.data[l])){ while l < self.n{ self.push(l); l *= 2; let res = F::op(&ac, &self.data[l]); if g(res.clone()){ ac = res; l += 1; } } return l-self.n; } ac = F::op(&ac, &self.data[l]); l += 1; let left = l as isize; (left&-left)!=left } {} self.n } pub fn min_left(&mut self, mut r: usize, g: G)->usize where G: Fn(::S)->bool{ assert!(g(F::id_e())); if r==0{return 0;} r += self.n; for i in (1..=self.log).rev(){ self.push((r-1)>>i); } let mut ac = F::id_e(); while { r -= 1; while r%2 != 0{ r >>= 1; } if !g(F::op(&self.data[r], &ac)){ while r < self.n{ self.push(r); r = 2*r+1; let res = F::op(&self.data[r], &ac); if g(res.clone()){ ac = res; r -= 1; } } return r+1-self.n; } ac = F::op(&self.data[r], &ac); let right = r as isize; (right&-right)!=right } {} 0 } pub fn get_slice(&mut self, mut l: usize, mut r: usize)->Vec<::S>{ l += self.n; r += self.n; for i in 1..self.n { self.push(i) } (l..r).into_iter().map(|z| self.data[z].clone()).collect() } } #[derive(Clone, Copy, Debug)] struct S{ num: i64, ac: i64, mx: i64, smx: i64, mi: i64, smi: i64, mx_c: i64, mi_c: i64, fail: bool, } impl S{ #[inline(always)] fn new(x: i64, n: i64)->Self{ S{ num: n, ac: n*x, mx: x, mi: x, smx: -INF, smi: INF, mx_c: n, mi_c: n, fail: false, } } } impl BeatsFail for S{ #[inline(always)] fn fail(&self) -> bool { self.fail } } struct M; impl SegtreeMonoid for M{ type S = S; fn identity() -> Self::S { S{ num: 0, ac: 0, mx: -INF, smx: -INF, mi: INF, smi: INF, mx_c: 0, mi_c: 0, fail: false, } } #[inline(always)] fn op(&a: &Self::S, &b: &Self::S) -> Self::S { if a.num==0{return b} if b.num==0{return a} let (mx, mx_c, smx) = if a.mx > b.mx{ (a.mx, a.mx_c, a.smx.max(b.mx)) } else if a.mx == b.mx{ (a.mx, a.mx_c+b.mx_c, a.smx.max(b.smx)) } else { (b.mx, b.mx_c, a.mx.max(b.smx)) }; let (mi, mi_c, smi) = if a.mi < b.mi{ (a.mi, a.mi_c, a.smi.min(b.mi)) } else if a.mi == b.mi{ (a.mi, a.mi_c+b.mi_c, a.smi.min(b.smi)) } else { (b.mi, b.mi_c, a.mi.min(b.smi)) }; S{ num: a.num+b.num, ac: a.ac+b.ac, mx, mx_c, smx, mi, mi_c, smi, fail: false, } } } struct MM; impl LazySegtreeMonoid for MM{ type M = M; // (chmin, chmax, add) // ub, lb, type F = (i64, i64, i64); fn identity() -> Self::F { (INF, -INF, 0) } #[inline(always)] fn map(&f: &Self::F, &x: &::S) -> ::S { if x.num == 0 { return x; } else if x.mx == x.mi || f.0 == f.1 || f.0 <= x.mi || f.1 >= x.mx{ return S::new(x.mi.max(f.1).min(f.0)+f.2, x.num); } else if x.smi==x.mx{ let mut res = x; res.mi = x.mi.max(f.1)+f.2; res.smx = res.mi; res.mx = x.mx.min(f.0)+f.2; res.smi = res.mx; res.ac = res.mi*res.mi_c+res.mx*res.mx_c; return res; } else if f.1 < x.smi && f.0 > x.smx{ let mut res = x; let nl = res.mi.max(f.1); let nh = res.mx.min(f.0); res.ac += (nl-res.mi)*res.mi_c-(res.mx-nh)*res.mx_c+f.2*res.num; res.mi = nl+f.2; res.mx = nh+f.2; res.smx += f.2; res.smi += f.2; return res; } let mut res = x; res.fail = true; res } #[inline(always)] fn composition(&f: &Self::F, &g: &Self::F) -> Self::F { let t = (g.1+g.2).min(f.0).max(f.1)-g.2; let b = (g.0+g.2).max(f.1).min(f.0)-g.2; let add = f.2+g.2; (b, t, add) } } use proconio::fastout; #[fastout] fn main(){ input!{ n: usize, k: usize, q: usize, a: [i64; n], update: [(Usize1, usize, i64); k], query: [(Usize1, usize, i64); q], } let mx = (k+3).next_power_of_two()-1; let mut b = vec![!0usize; q]; let mut t = vec![mx; q]; let base = a.iter().map(|&x| S::new(x, 1)).collect::>(); while b[0].wrapping_add(1) < t[0]{ let mut qs = vec![Vec::new(); mx]; for (i, &(l, r, x)) in query.iter().enumerate(){ let m = (b[i].wrapping_add(t[i]))/2; qs[m].push((l, r, x, i)); } let mut segtree = LazySegtree::::build(&base); for (i, vc) in qs.iter().enumerate(){ if 0 < i && i <= k{ let (l, r, x) = update[i-1]; segtree.apply_range(l, r, (INF, x, 0)); } for &(l, r, x, idx) in vc{ if segtree.prod(l, r).ac >= x{ t[idx] = i; } else { b[idx] = i; } } } } for r in t{ if r > k{ println!("-1"); } else { println!("{}", r); } } } #[allow(unused)] fn solver(){ input!{ n: usize, k: usize, q: usize, a: [i64; n], update: [(Usize1, usize, i64); k], query: [(Usize1, usize, i64); q], } let mut ans2 = Vec::with_capacity(q); for &(b, t, y) in &query{ let mut ok = false; let mut vc = a.clone(); for (i, &(l, r, x)) in update.iter().enumerate(){ let mut ac = 0; for i in b..t{ ac += vc[i]; } if ac >= y{ ok = true; ans2.push(i as i64); break; } else { for i in l..r{ vc[i] = vc[i].max(x); } } } if !ok{ let mut ac = 0; for i in b..t{ ac += vc[i]; } if ac >= y{ ans2.push(k as i64); } else { ans2.push(-1); } } } println!("{}", ans2.iter().map(|x| x.to_string()).collect::>().join("\n")) }