File tree Expand file tree Collapse file tree 3 files changed +84
-0
lines changed
Expand file tree Collapse file tree 3 files changed +84
-0
lines changed Original file line number Diff line number Diff line change @@ -216,6 +216,10 @@ path = "examples/monotonic/count_rects.rs"
216216name = " cartesian_tree"
217217path = " examples/monotonic/cartesian_tree.rs"
218218
219+ [[example ]]
220+ name = " fenwick_kth"
221+ path = " examples/data_structures/fenwick_kth.rs"
222+
219223[[example ]]
220224name = " disjoint_rmq_non_commutative"
221225path = " examples/data_structures/disjoint_rmq_non_commutative.rs"
Original file line number Diff line number Diff line change 1+ // verification-helper: PROBLEM https://judge.yosupo.jp/problem/predecessor_problem
2+
3+ use proconio:: input;
4+ use programming_team_code_rust:: data_structures:: fenwick:: Fenwick ;
5+
6+ fn main ( ) {
7+ input ! {
8+ n: usize ,
9+ q: usize ,
10+ s: String ,
11+ }
12+
13+ let mut fenwick =
14+ Fenwick :: < i32 > :: build_on_array ( & s. chars ( ) . map ( |c| ( c == '1' ) as i32 ) . collect :: < Vec < _ > > ( ) ) ;
15+
16+ for _ in 0 ..q {
17+ input ! {
18+ t: u8 ,
19+ k: usize ,
20+ }
21+ match t {
22+ 0 => {
23+ if fenwick. sum ( k..k + 1 ) == 0 {
24+ fenwick. add ( k, 1 ) ;
25+ }
26+ }
27+ 1 => {
28+ if fenwick. sum ( k..k + 1 ) == 1 {
29+ fenwick. add ( k, -1 ) ;
30+ }
31+ }
32+ 2 => {
33+ println ! ( "{}" , fenwick. sum( k..k + 1 ) ) ;
34+ }
35+ 3 => {
36+ let cnt = fenwick. sum ( 0 ..k) ;
37+ let res = fenwick. kth ( cnt + 1 ) ;
38+ if res == n {
39+ println ! ( "-1" ) ;
40+ } else {
41+ println ! ( "{}" , res) ;
42+ }
43+ }
44+ _ => {
45+ let cnt_le = fenwick. sum ( 0 ..k + 1 ) ;
46+ if cnt_le == 0 {
47+ println ! ( "-1" ) ;
48+ } else {
49+ println ! ( "{}" , fenwick. kth( cnt_le) ) ;
50+ }
51+ }
52+ }
53+ }
54+ }
Original file line number Diff line number Diff line change 99/// fenwick.add(2, 2);
1010/// fenwick.add(3, 1);
1111/// assert_eq!(fenwick.sum(1..3), 5);
12+ /// assert_eq!(fenwick.kth(5), 2);
13+ /// assert!(std::panic::catch_unwind(|| fenwick.kth(0)).is_err());
1214/// ```
1315pub struct Fenwick < T > {
1416 ary : Vec < T > ,
@@ -75,4 +77,28 @@ impl<T: Clone + Default + std::ops::AddAssign<T>> Fenwick<T> {
7577 {
7678 self . accum ( range. end ) - self . accum ( range. start )
7779 }
80+
81+ /// Gets maximum pos such that sum of [0, pos) < sum
82+ ///
83+ /// Requires fenwick.sum(i..i + 1) >= 0 and sum > 0
84+ ///
85+ /// # Complexity
86+ /// - Time: O(log n)
87+ /// - Space: O(1)
88+ pub fn kth ( & self , mut sum : T ) -> usize
89+ where
90+ T : std:: ops:: SubAssign < T > + std:: cmp:: PartialOrd ,
91+ {
92+ assert ! ( sum > T :: default ( ) ) ;
93+ let mut pos = 0 ;
94+ let mut pw = self . ary . len ( ) . next_power_of_two ( ) ;
95+ while pw > 0 {
96+ if pos + pw <= self . ary . len ( ) && self . ary [ pos + pw - 1 ] < sum {
97+ pos += pw;
98+ sum -= self . ary [ pos - 1 ] . clone ( ) ;
99+ }
100+ pw /= 2 ;
101+ }
102+ pos
103+ }
78104}
You can’t perform that action at this time.
0 commit comments