Skip to content

Commit c7d2f5c

Browse files
committed
1157
1 parent f8b00fd commit c7d2f5c

File tree

2 files changed

+239
-0
lines changed

2 files changed

+239
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ mod prob_1059;
320320
mod prob_1092;
321321
mod prob_1109;
322322
mod prob_1135;
323+
mod prob_1157;
323324
mod prob_1167;
324325
mod prob_1228;
325326
mod prob_1229;

src/prob_1157.rs

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
use std::collections::HashMap;
2+
3+
struct MajorityChecker {
4+
arr: Vec<i32>,
5+
threshold: i32,
6+
maybe: Vec<i32>,
7+
sum: Vec<Vec<i32>>,
8+
}
9+
10+
impl MajorityChecker {
11+
fn new(arr: Vec<i32>) -> Self {
12+
let n = arr.len();
13+
let threshold = ((2*n) as f64).sqrt() as i32;
14+
let mut hash = HashMap::new();
15+
for &v in &arr {
16+
*hash.entry(v).or_insert(0) += 1;
17+
}
18+
let mut maybe = vec![];
19+
let mut sum = vec![];
20+
for (&k,&v) in hash.iter() {
21+
if v > threshold {
22+
maybe.push(k);
23+
let mut t = vec![0; n+1];
24+
for i in 0..n {
25+
if arr[i] == k {
26+
t[i+1] = t[i]+1;
27+
} else {
28+
t[i+1] = t[i];
29+
}
30+
}
31+
sum.push(t);
32+
}
33+
}
34+
Self{
35+
arr,
36+
threshold,
37+
maybe,
38+
sum,
39+
}
40+
}
41+
42+
fn query(&self, left: i32, right: i32, threshold: i32) -> i32 {
43+
let s = right-left+1;
44+
if s <= self.threshold {
45+
return self.count(left,right,threshold);
46+
}
47+
let l = left as usize;
48+
let r = right as usize;
49+
for (i, &v) in self.maybe.iter().enumerate() {
50+
if self.sum[i][r+1]-self.sum[i][l] >= threshold {
51+
return v;
52+
}
53+
}
54+
-1
55+
}
56+
fn count(&self, left: i32, right: i32, threshold: i32) -> i32 {
57+
let mut i = left as usize;
58+
let mut acc = 0;
59+
let r = right as usize;
60+
let mut t = -1;
61+
while i <= r {
62+
if acc == 0 {
63+
t = self.arr[i];
64+
acc += 1;
65+
i+=1;
66+
continue;
67+
}
68+
if self.arr[i] == t {
69+
acc+=1;
70+
} else {
71+
acc-=1;
72+
}
73+
i+=1;
74+
}
75+
if acc == 0 {
76+
return -1;
77+
}
78+
if (left..=right).into_iter().filter(|&i| self.arr[i as usize]==t).count() as i32 >= threshold {
79+
t
80+
} else {
81+
-1
82+
}
83+
}
84+
}
85+
86+
struct TreeChecker {
87+
t: Option<Box<SegmentTree>>,
88+
pos: HashMap<i32, Vec<usize>>,
89+
n: i32,
90+
}
91+
92+
struct SegmentTree {
93+
lch: Option<Box<SegmentTree>>,
94+
rch: Option<Box<SegmentTree>>,
95+
val: i32,
96+
count: i32,
97+
}
98+
99+
impl SegmentTree {
100+
fn new(arr: &Vec<i32>, l: i32, r: i32) -> Option<Box<Self>> {
101+
if l == r {
102+
return Some(Box::new(SegmentTree{
103+
lch: None,
104+
rch: None,
105+
val: arr[l as usize],
106+
count: 1,
107+
}));
108+
}
109+
let m = (l+r)/2;
110+
let lch = Self::new(arr, l, m);
111+
let rch = Self::new(arr, m+1, r);
112+
let (lv, lc) = {
113+
let p = lch.as_ref().unwrap();
114+
(p.val, p.count)
115+
};
116+
let (rv, rc) = {
117+
let p = rch.as_ref().unwrap();
118+
(p.val, p.count)
119+
};
120+
if lv == rv {
121+
Some(Box::new(SegmentTree{
122+
lch,
123+
rch,
124+
val: lv,
125+
count: lc+rc,
126+
}))
127+
} else {
128+
if lc >= rc {
129+
Some(Box::new(SegmentTree{
130+
lch,
131+
rch,
132+
val: lv,
133+
count: lc-rc,
134+
}))
135+
} else {
136+
Some(Box::new(SegmentTree{
137+
lch,
138+
rch,
139+
val: rv,
140+
count: rc-lc,
141+
}))
142+
}
143+
}
144+
}
145+
fn query(&self, l: i32, r: i32, left: i32, right: i32) -> (i32, i32) {
146+
if l == left && r == right {
147+
return (self.val, self.count);
148+
}
149+
let m = (l+r)/2;
150+
if right <= m {
151+
self.lch.as_ref().unwrap().query(l, m, left, right)
152+
} else if left > m {
153+
self.rch.as_ref().unwrap().query(m+1, r, left, right)
154+
} else {
155+
let (lv, lc) = self.lch.as_ref().unwrap().query(l, m, left, m);
156+
let (rv, rc) = self.rch.as_ref().unwrap().query(m+1, r, m+1, right);
157+
if lc >= rc {
158+
(lv, lc)
159+
} else {
160+
(rv, rc)
161+
}
162+
}
163+
}
164+
}
165+
166+
impl TreeChecker {
167+
fn new(arr: Vec<i32>) -> Self {
168+
let t = SegmentTree::new(&arr, 0, arr.len() as i32-1);
169+
let mut pos = HashMap::new();
170+
for (i, &v) in arr.iter().enumerate() {
171+
pos.entry(v).or_insert(vec![]).push(i);
172+
}
173+
Self{
174+
t,
175+
pos,
176+
n: arr.len() as i32-1,
177+
}
178+
}
179+
fn query(&self, left: i32, right: i32, threshold: i32) -> i32 {
180+
let (v, _) = self.t.as_ref().unwrap().query(0, self.n, left, right);
181+
if let Some(pos) = self.pos.get(&v) {
182+
match (pos.binary_search(&(left as usize)), pos.binary_search(&(right as usize))) {
183+
(Err(a), Err(b)) => {
184+
if b-a >= threshold as usize {
185+
return v;
186+
}
187+
},
188+
(Ok(a), Ok(b)) => {
189+
if b-a+1 >= threshold as usize {
190+
return v;
191+
}
192+
},
193+
(Err(a), Ok(b)) => {
194+
if b-a+1 >= threshold as usize {
195+
return v;
196+
}
197+
},
198+
(Ok(a), Err(b)) => {
199+
if b-a >= threshold as usize {
200+
return v;
201+
}
202+
}
203+
}
204+
}
205+
-1
206+
}
207+
}
208+
209+
#[cfg(test)]
210+
mod tests {
211+
use super::MajorityChecker;
212+
use super::TreeChecker;
213+
214+
#[test]
215+
fn test_sqrt() {
216+
let mut t = MajorityChecker::new(vec![1,1,2,2,1,1]);
217+
let test_cases = vec![
218+
(2,3,2, 2),
219+
(0,5,4, 1),
220+
(0,3,3, -1),
221+
];
222+
for (l,r,threshold, expect) in test_cases {
223+
assert_eq!(t.query(l,r, threshold), expect, "l:{}, r:{}, threshold:{}", l, r, threshold);
224+
}
225+
}
226+
#[test]
227+
fn test_tree() {
228+
let mut t = TreeChecker::new(vec![1,1,2,2,1,1]);
229+
let test_cases = vec![
230+
(0,5,4, 1),
231+
(2,3,2, 2),
232+
(0,3,3, -1),
233+
];
234+
for (l,r,threshold, expect) in test_cases {
235+
assert_eq!(t.query(l,r, threshold), expect, "l:{}, r:{}, threshold:{}", l, r, threshold);
236+
}
237+
}
238+
}

0 commit comments

Comments
 (0)