Skip to content

Commit 130ee4c

Browse files
authored
Update 1157-online-majority-element-in-subarray.js
1 parent aea984e commit 130ee4c

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

1157-online-majority-element-in-subarray.js

+138
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,141 @@
1+
function Bisect() {
2+
return { insort_right, insort_left, bisect_left, bisect_right }
3+
function insort_right(a, x, lo = 0, hi = null) {
4+
lo = bisect_right(a, x, lo, hi)
5+
a.splice(lo, 0, x)
6+
}
7+
function bisect_right(a, x, lo = 0, hi = null) {
8+
if (lo < 0) throw new Error('lo must be non-negative')
9+
if (hi == null) hi = a.length
10+
while (lo < hi) {
11+
let mid = (lo + hi) >> 1
12+
x < a[mid] ? (hi = mid) : (lo = mid + 1)
13+
}
14+
return lo
15+
}
16+
function insort_left(a, x, lo = 0, hi = null) {
17+
lo = bisect_left(a, x, lo, hi)
18+
a.splice(lo, 0, x)
19+
}
20+
function bisect_left(a, x, lo = 0, hi = null) {
21+
if (lo < 0) throw new Error('lo must be non-negative')
22+
if (hi == null) hi = a.length
23+
while (lo < hi) {
24+
let mid = (lo + hi) >> 1
25+
a[mid] < x ? (lo = mid + 1) : (hi = mid)
26+
}
27+
return lo
28+
}
29+
}
30+
31+
function SegmentTreeRQ(m, A, n) {
32+
let bisect = new Bisect()
33+
let h = Math.ceil(Math.log2(n))
34+
const MAX = 2 * 2 ** h - 1
35+
let tree = Array(MAX).fill(-1)
36+
let a = [...A]
37+
build(1, 0, n - 1)
38+
return {
39+
query,
40+
}
41+
42+
function build(vi, tl, tr) {
43+
if (tl == tr) {
44+
tree[vi] = a[tl]
45+
return
46+
}
47+
let mid = getMid(tl, tr)
48+
build(vi * 2, tl, mid)
49+
build(vi * 2 + 1, mid + 1, tr)
50+
if (
51+
tree[vi * 2] != -1 &&
52+
get_occurrence(tree[vi * 2], tl, tr) * 2 > tr - tl + 1
53+
) {
54+
tree[vi] = tree[vi * 2]
55+
} else if (
56+
tree[vi * 2 + 1] != -1 &&
57+
get_occurrence(tree[vi * 2 + 1], tl, tr) * 2 > tr - tl + 1
58+
) {
59+
tree[vi] = tree[vi * 2 + 1]
60+
}
61+
}
62+
63+
function query(vi, l, r, tl, tr) {
64+
if (l > tr || r < tl) {
65+
return {
66+
first: -1,
67+
second: -1,
68+
}
69+
}
70+
if (tl <= l && r <= tr) {
71+
if (tree[vi] == -1)
72+
return {
73+
first: -1,
74+
second: -1,
75+
}
76+
let occ = get_occurrence(tree[vi], tl, tr)
77+
if (occ * 2 > tr - tl + 1) {
78+
return {
79+
first: tree[vi],
80+
second: occ,
81+
}
82+
} else {
83+
return {
84+
first: -1,
85+
second: -1,
86+
}
87+
}
88+
}
89+
let mid = getMid(l, r)
90+
let resL = query(vi * 2, l, mid, tl, tr)
91+
if (resL.first > -1) return resL
92+
let resR = query(vi * 2 + 1, mid + 1, r, tl, tr)
93+
if (resR.first > -1) return resR
94+
return {
95+
first: -1,
96+
second: -1,
97+
}
98+
}
99+
100+
function get_occurrence(num, l, r) {
101+
// only difference
102+
if (!m.has(num)) return 0
103+
let a = m.get(num)
104+
let lbv = bisect.bisect_left(a, l) //lower_bound
105+
if (lbv == a.length) return 0
106+
let ubv = bisect.bisect_right(a, r) // upper_bound
107+
return ubv - lbv
108+
}
109+
110+
function getMid(low, high) {
111+
return low + ((high - low) >> 1)
112+
}
113+
}
114+
115+
function MajorityChecker(a) {
116+
let m = new Map()
117+
let n = a.length
118+
for (let i = 0; i < n; i++) {
119+
if (!m.has(a[i])) m.set(a[i], [])
120+
m.get(a[i]).push(i)
121+
}
122+
let st = new SegmentTreeRQ(m, a, n)
123+
return {
124+
query,
125+
}
126+
127+
function query(left, right, threshold) {
128+
let res = st.query(1, 0, n - 1, left, right)
129+
if (res.second >= threshold) {
130+
return res.first
131+
}
132+
return -1
133+
}
134+
}
135+
136+
// another
137+
138+
1139
/**
2140
* @param {number[]} arr
3141
*/

0 commit comments

Comments
 (0)