結果
問題 |
No.3122 Median of Medians of Division
|
ユーザー |
|
提出日時 | 2025-04-19 13:19:24 |
言語 | Rust (1.83.0 + proconio) |
結果 |
RE
|
実行時間 | - |
コード長 | 6,294 bytes |
コンパイル時間 | 11,228 ms |
コンパイル使用メモリ | 402,020 KB |
実行使用メモリ | 9,040 KB |
最終ジャッジ日時 | 2025-04-19 13:19:41 |
合計ジャッジ時間 | 14,856 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | RE * 1 |
other | RE * 40 |
コンパイルメッセージ
warning: unreachable statement --> src/main.rs:16:5 | 14 | panic!(); | -------- any code following this expression is unreachable 15 | 16 | let mut qs=vec![]; | ^^^^^^^^^^^^^^^^^^ unreachable statement | = note: `#[warn(unreachable_code)]` on by default warning: unused variable: `q` --> src/main.rs:10:9 | 10 | q:usize, | ^ help: if this is intentional, prefix it with an underscore: `_q` | = note: `#[warn(unused_variables)]` on by default warning: unused variable: `a` --> src/main.rs:11:9 | 11 | a:[usize;n], | ^ help: if this is intentional, prefix it with an underscore: `_a`
ソースコード
#![allow(unused_imports,non_snake_case,dead_code)] use std::{cmp::Reverse as Rev,collections::*,iter::*}; use proconio::{marker::*,*}; #[fastout] fn main(){ input!{ n:usize, q:usize, a:[usize;n], } panic!(); let mut qs=vec![]; for _ in 0..q{ input!{ t:usize, } if t==1{ // change input!{ i:Usize1, x:usize, } let new=Q{ t:Change,i,x, l:!0,r:!0, }; qs.push(new); } else{ // get input!{ l:Usize1, r:usize, } let new=Q{ t:Get,i:!0,x:!0, l,r, }; qs.push(new); } } let mut seq_ps=vec![]; let mut adj_ps=vec![]; { let mut a=a.clone(); for i in 0..n{ seq_ps.push((i,a[i])); if 1<=i{ adj_ps.push((i-1,a[i-1].max(a[i]))); } } for &q in &qs{ if q.t!=Change{ continue; } a[q.i]=q.x; seq_ps.push((q.i,q.x)); if 1<=q.i{ adj_ps.push((q.i-1,a[q.i-1].max(a[q.i]))); } if q.i+1<a.len(){ adj_ps.push((q.i,a[q.i].max(a[q.i+1]))); } } } let mut seq=R::new(0,seq_ps); let mut adj=R::new(0,adj_ps); let mut a=a; let get=|re:&R,l:usize,r:usize,a:usize|->i64{ assert!(0<=a as i64); let right=if (r as i64)<0{ 0 } else{ re.find(r,a) }; let left=if (l as i64)<0{ 0 } else{ re.find(l,a) }; assert!(left<=right); right-left }; for i in 0..n{ seq.add(i,a[i],1); if 1<=i{ adj.add(i-1,a[i-1].max(a[i]),1); } } for &q in &qs{ if q.t==Change{ let i=q.i; let x=q.x; seq.add(i,a[i],-1); seq.add(i,x,1); if 1<=i{ adj.add(i-1,a[i-1].max(a[i]),-1); adj.add(i-1,a[i-1].max(x),1); } if i+1<a.len(){ adj.add(i,a[i].max(a[i+1]),-1); adj.add(i,x.max(a[i+1]),1); } a[i]=x; } else{ let l=q.l; let r=q.r; let mut ok=0; let mut ng=1e9 as usize+1; // eprintln!("Query: {:?}",&a[l..r]); while ng-ok>1{ let m=(ok+ng)/2; let z=get(&adj,l-1,r-2,m-1); // [l,r)で隣接する2つがどっちもm未満である場所の数 // assert!(z==verify_z(&a[l..r],m)); let y=get(&seq,l-1,r-1,m-1); // [l,r)でm未満の場所の数 // assert!(y==verify_y(&a[l..r],m)); let x=y-z; // // [l,r)でk未満の連続部分列の個数 // eprintln!("{m} : {} {} {}",x,y,z); if x as usize<=(r-l-y as usize+x as usize-1)/2{ ok=m; } else{ ng=m; } } // eprintln!(); println!("{ok}"); } } } fn verify_z(a:&[usize],m:usize)->i64{ let mut ret=0; for i in 1..a.len(){ ret+=(a[i-1].max(a[i])<m) as i64; } ret } fn verify_y(a:&[usize],m:usize)->i64{ let mut ret=0; for i in 0..a.len(){ ret+=(a[i]<m) as i64; } ret } #[derive(Clone,Copy,PartialEq,Eq)] enum T{ Change,Get, } use T::*; #[derive(Clone,Copy)] struct Q{ t:T, i:usize, x:usize, l:usize, r:usize, } type R=RectangleSum<usize,i64>; // 窃盗:https://judge.yosupo.jp/submission/33203 // ありがとうございます... struct RectangleSum<Index, Weight> { point: Vec<(Index, Index)>, row: Vec<Index>, col: Vec<Vec<Index>>, bit: Vec<Vec<Weight>>, zero: Weight, } impl<Index, Weight> RectangleSum<Index, Weight> where Index: Ord + Copy, Weight: std::ops::Add<Output = Weight> + Copy, { fn new(zero: Weight, point: Vec<(Index, Index)>) -> Self { let mut r=RectangleSum { point, row: vec![], col: vec![], bit: vec![], zero: zero, }; r.build(); r } fn build(&mut self) { let mut row: Vec<_> = self.point.iter().map(|p| p.0).collect(); row.sort(); row.dedup(); let mut col = vec![vec![]; row.len() + 1]; for &(x, y) in self.point.iter() { let mut k = row.binary_search(&x).unwrap() + 1; while let Some(a) = col.get_mut(k) { a.push(y); k += k & (!k + 1); } } let mut bit = vec![vec![]; row.len() + 1]; for (bit, col) in bit.iter_mut().zip(col.iter_mut()).skip(1) { col.sort(); col.dedup(); bit.resize(col.len() + 1, self.zero); } self.row = row; self.col = col; self.bit = bit; } fn add(&mut self, x: Index, y: Index, w: Weight) { let mut x = self.row.binary_search(&x).unwrap() + 1; while let Some(bit) = self.bit.get_mut(x) { let mut y = self.col[x].binary_search(&y).unwrap() + 1; while let Some(v) = bit.get_mut(y) { *v = *v + w; y += y & (!y + 1); } x += x & (!x + 1); } } // (-inf, x] * (-inf * y] の和 fn find(&self, x: Index, y: Index) -> Weight { let upper_bound = |x: &[Index], v: &Index| -> usize { use std::cmp::Ordering::Less; x.binary_search_by(|p| p.cmp(v).then(Less)).unwrap_err() }; let mut x = upper_bound(&self.row, &x); let mut ans = self.zero; while x > 0 { let mut y = upper_bound(&self.col[x], &y); let bit = &self.bit[x]; while y > 0 { ans = ans + bit[y]; y -= y & (!y + 1); } x -= x & (!x + 1); } ans } }