Skip to content

Commit 630f932

Browse files
committed
static bitset size dispatch
1 parent 8d0dc39 commit 630f932

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
// https://codeforces.com/blog/entry/143059
4+
template <unsigned long long sz = 1>
5+
void static_bitset_size_dispatch(unsigned long long n, auto &&callback) {
6+
if constexpr (sz > (1ULL << 30)) {
7+
return;
8+
} else if (n > sz) {
9+
static_bitset_size_dispatch<((sz * 3 + 1) / 2)>(n, callback); // tune here
10+
} else {
11+
callback.template operator()<sz>();
12+
}
13+
}
14+
/* Usage:
15+
int ret = 0;
16+
static_bitset_size_dispatch(n, [&]<size_t BS_SIZE>() {
17+
std::bitset<BS_SIZE> bs;
18+
// do something...
19+
// ret = ...;
20+
});
21+
*/
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
title: Static bitset size dispatch (コンパイル時 bitset サイズの実行時分岐)
3+
documentation_of: ./static_bitset_size_dispatch.hpp
4+
---
5+
6+
実行時に決まるサイズ $n$ に対して,$n$ 以上の最小のコンパイル時定数をテンプレート引数として `std::bitset` 等を利用できるようにするユーティリティ.サイズの候補は $1$ から約 $\alpha = 1.5$ 倍ずつ増加し,$2^{30}$ を上限とする.
7+
8+
## 使用方法
9+
10+
```cpp
11+
static_bitset_size_dispatch(n, [&]<size_t BS_SIZE>() {
12+
std::bitset<BS_SIZE> bs;
13+
// BS_SIZE >= n が保証される
14+
});
15+
```
16+
17+
- `n`: 必要なビットサイズ(`unsigned long long`).
18+
- `callback`: テンプレート引数 `BS_SIZE`(`n` 以上のコンパイル時定数)を受け取るジェネリックラムダ.
19+
20+
コンパイル時にサイズ候補ごとのインスタンスが生成される.増加率を $\alpha$ として, `n` がおおよそ $2^{30} / \alpha$ 以上の場合は何も実行されない可能性がある.
21+
22+
## 問題例
23+
24+
- [Codeforces Round 1079 (Div. 1) E2. Fuzzy Concatenation (Hard version)](https://codeforces.com/contest/2196/problem/E2)
25+
- [Submission #362639741 - Codeforces](https://codeforces.com/contest/2196/submission/362639741)
26+
27+
## リンク
28+
29+
- [Variable size bitset (kind of) - Codeforces](https://codeforces.com/blog/entry/143059)

0 commit comments

Comments
 (0)