-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy path_898.java
64 lines (56 loc) · 1.85 KB
/
_898.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.util.HashSet;
import java.util.Set;
/**
* LeetCode 898 - Bitwise ORs of Subarrays
* <p>
* Divide-and-Conquer approach of runtime O(n (log n + 32^2)).
*/
public class _898 {
Set<Integer> ans;
public int subarrayBitwiseORs(int[] A) {
ans = new HashSet<>();
dfs(A, 0, A.length - 1, new int[A.length]);
return ans.size();
}
void dfs(int[] A, int l, int r, int[] or) {
if (l == r) {
ans.add(A[l]);
} else {
int mid = (l + r) / 2, full = 0;
dfs(A, l, mid, or);
dfs(A, mid + 1, r, or);
int mask = 0;
int L = mid, R = mid + 1;
for (int i = mid; i >= l; i--) {
mask |= A[i];
full |= A[i];
if (L == mid || mask != or[L + 1]) {
or[L] = mask;
L--;
}
}
mask = 0;
for (int i = mid + 1; i <= r; i++) {
mask |= A[i];
full |= A[i];
if (R == mid + 1 || mask != or[R - 1]) {
or[R] = mask;
R++;
}
}
// Now, or[L+1, mid] stores all distinct or-values of subarrays in the form of A[i, mid], where l <= i <= mid.
// Similary, or[mid+1, R-1] stores all distinct or-values of subarrays in the form of A[mid+1, i], where mid+1 <= i <= r.
// Note that, there will be at most 32 distinct elements on each side.
for (int i = mid; i > L; i--) {
for (int j = mid + 1; j < R; j++) {
mask = or[i] | or[j];
ans.add(mask);
// Another optimization
if (mask == full) {
break;
}
}
}
}
}
}