/
parallel_binary_search.hpp
44 lines (43 loc) · 1.13 KB
/
parallel_binary_search.hpp
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
/*
並列二分探索。(Q, ok, ng, init, upd, check)。
check が成り立つぎりぎりの upd回数を返す。
・void upd(t):t 回目の update
・bool check(q):クエリ q の判定
*/
template <typename F1, typename F2, typename F3>
vc<int> parallel_binary_search(int Q, int ok, int ng, F1 init, F2 upd,
F3 check) {
int T = max(ok, ng);
vc<int> OK(Q, ok), NG(Q, ng);
while (1) {
vc<int> check_t(Q, -1);
FOR(q, Q) {
int& t = check_t[q];
if (abs(OK[q] - NG[q]) > 1) { t = (OK[q] + NG[q]) / 2; }
}
vc<int> indptr(T + 1);
FOR(q, Q) {
int& t = check_t[q];
if (t != -1) indptr[t + 1]++;
}
FOR(t, T) indptr[t + 1] += indptr[t];
int total = indptr.back();
if (total == 0) break;
auto counter = indptr;
vc<int> csr(total);
FOR(q, Q) {
int& t = check_t[q];
if (t != -1) { csr[counter[t]++] = q; }
}
init();
int t = 0;
for (auto&& q: csr) {
while (t < check_t[q]) { upd(t++); }
if (check(q))
OK[q] = t;
else
NG[q] = t;
}
}
return OK;
}