Skip to content

Commit c6d9320

Browse files
committed
Remove bitpack, add util functions on bit_array instead
1 parent b42fe3b commit c6d9320

File tree

10 files changed

+143
-131
lines changed

10 files changed

+143
-131
lines changed

cp-algo/min/structures/bitpack.hpp

Lines changed: 0 additions & 10 deletions
This file was deleted.

cp-algo/structures/bit_array.hpp

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
#ifndef CP_ALGO_STRUCTURES_BIT_ARRAY_HPP
22
#define CP_ALGO_STRUCTURES_BIT_ARRAY_HPP
33
#include "../util/bit.hpp"
4+
#include "../util/big_alloc.hpp"
45
#include <cassert>
6+
CP_ALGO_BIT_PRAGMA_PUSH
57
namespace cp_algo::structures {
68
template<typename C>
79
concept Resizable = requires(C& c, std::size_t n) { c.resize(n); };
810

911
template<class Cont>
1012
struct _bit_array {
11-
static constexpr size_t width = bit_width<uint64_t>;
13+
using word_t = typename Cont::value_type;
14+
static constexpr size_t width = bit_width<word_t>;
1215
size_t words, n;
1316
alignas(32) Cont data;
1417

@@ -22,18 +25,24 @@ namespace cp_algo::structures {
2225
}
2326
}
2427

25-
constexpr _bit_array(): n(0), words(0), data() {}
28+
constexpr _bit_array(): data() {
29+
if constexpr (!Resizable<Cont>) {
30+
resize(std::size(data) * width);
31+
} else {
32+
resize(0);
33+
}
34+
}
2635
constexpr _bit_array(size_t N): data() {
2736
resize(N);
2837
}
2938

30-
constexpr uint64_t& word(size_t x) {
39+
constexpr word_t& word(size_t x) {
3140
return data[x];
3241
}
33-
constexpr uint64_t word(size_t x) const {
42+
constexpr word_t word(size_t x) const {
3443
return data[x];
3544
}
36-
constexpr void set_all(uint64_t val = -1) {
45+
constexpr void set_all(word_t val = -1) {
3746
for(auto& w: data) {w = val;}
3847
}
3948
constexpr void reset() {
@@ -57,21 +66,26 @@ namespace cp_algo::structures {
5766
constexpr size_t size() const {
5867
return n;
5968
}
60-
};
61-
62-
template<size_t N>
63-
struct bit_array: _bit_array<std::array<uint64_t, (N + 63) / 64>> {
64-
using Base = _bit_array<std::array<uint64_t, (N + 63) / 64>>;
65-
using Base::Base, Base::words, Base::data;
66-
constexpr bit_array(): Base(N) {}
67-
};
68-
struct dynamic_bit_array: _bit_array<std::vector<uint64_t>> {
69-
using Base = _bit_array<std::vector<uint64_t>>;
70-
using Base::Base, Base::words;
71-
constexpr dynamic_bit_array(size_t N): Base(N) {
72-
data.resize(words);
69+
70+
auto operator <=> (_bit_array const& t) const = default;
71+
72+
constexpr _bit_array& xor_hint(_bit_array const& t, size_t hint) {
73+
for(size_t i = hint / width; i < std::size(data); i++) {
74+
data[i] ^= t.data[i];
75+
}
76+
return *this;
77+
}
78+
constexpr _bit_array& operator ^= (_bit_array const& t) {
79+
return xor_hint(t, 0);
80+
}
81+
constexpr _bit_array operator ^ (_bit_array const& t) const {
82+
return _bit_array(*this) ^= t;
7383
}
7484
};
7585

86+
template<size_t N>
87+
using bit_array = _bit_array<std::array<uint64_t, (N + 63) / 64>>;
88+
using dynamic_bit_array = _bit_array<big_vector<uint64_t>>;
7689
}
90+
#pragma GCC pop_options
7791
#endif // CP_ALGO_STRUCTURES_BIT_ARRAY_HPP
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#ifndef CP_ALGO_STRUCTURES_BIT_ARRAY_UTIL_HPP
2+
#define CP_ALGO_STRUCTURES_BIT_ARRAY_UTIL_HPP
3+
#include "../structures/bit_array.hpp"
4+
#include "../util/bit.hpp"
5+
#include <cstdint>
6+
#include <cstddef>
7+
#include <string>
8+
#include <array>
9+
#include <span>
10+
CP_ALGO_BIT_PRAGMA_PUSH
11+
namespace cp_algo::structures {
12+
template<typename BitArray>
13+
constexpr void from_string(BitArray& arr, std::span<char> bits) {
14+
arr.resize(std::size(bits));
15+
int64_t i = 0;
16+
constexpr int width = BitArray::width;
17+
for(; i + width <= (int64_t)std::size(bits); i += width) {
18+
arr.word(i / width) = read_bits64(bits.data() + i);
19+
}
20+
for(; i < (int64_t)std::size(bits); i++) {
21+
if(bits[i] & 1) {
22+
arr.set(i);
23+
}
24+
}
25+
}
26+
27+
template<typename BitArray>
28+
constexpr big_string to_string(BitArray const& arr) {
29+
big_string res(arr.words * BitArray::width, '0');
30+
for(size_t i = 0; i < arr.words; i++) {
31+
write_bits64(res.data() + i * BitArray::width, arr.word(i));
32+
}
33+
res.resize(arr.n);
34+
return res;
35+
}
36+
37+
template<typename BitArray>
38+
constexpr size_t count(BitArray const& arr, size_t n) {
39+
size_t res = 0;
40+
for(size_t i = 0; i < n / BitArray::width; i++) {
41+
res += std::popcount(arr.word(i));
42+
}
43+
if (n % BitArray::width) {
44+
res += std::popcount(arr.word(n / BitArray::width) & mask(n % BitArray::width));
45+
}
46+
return res;
47+
}
48+
49+
template<typename BitArray>
50+
constexpr size_t count(BitArray const& arr) {
51+
return count(arr, arr.n);
52+
}
53+
54+
template<typename BitArray>
55+
constexpr size_t ctz(BitArray const& arr) {
56+
size_t res = 0;
57+
size_t i = 0;
58+
while(i < arr.words && arr.word(i) == 0) {
59+
res += BitArray::width;
60+
i++;
61+
}
62+
if(i < arr.words) {
63+
res += std::countr_zero(arr.word(i));
64+
}
65+
return std::min(res, arr.n);
66+
}
67+
}
68+
#pragma GCC pop_options
69+
#endif // CP_ALGO_STRUCTURES_BIT_ARRAY_UTIL_HPP

cp-algo/structures/bitpack.hpp

Lines changed: 0 additions & 76 deletions
This file was deleted.

cp-algo/util/bit.hpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,21 @@
22
#define CP_ALGO_UTIL_BIT_HPP
33
#include "../util/simd.hpp"
44
#include <cstdint>
5+
#include <cstddef>
56
#include <array>
67
#include <bit>
7-
CP_ALGO_SIMD_PRAGMA_PUSH
8+
9+
#if defined(__x86_64__) && !defined(CP_ALGO_DISABLE_AVX2)
10+
#define CP_ALGO_BIT_OPS_TARGET _Pragma("GCC target(\"avx2,bmi,bmi2,lzcnt,popcnt\")")
11+
#else
12+
#define CP_ALGO_BIT_OPS_TARGET _Pragma("GCC target(\"bmi,bmi2,lzcnt,popcnt\")")
13+
#endif
14+
15+
#define CP_ALGO_BIT_PRAGMA_PUSH \
16+
_Pragma("GCC push_options") \
17+
CP_ALGO_BIT_OPS_TARGET
18+
19+
CP_ALGO_BIT_PRAGMA_PUSH
820
namespace cp_algo {
921
template<typename Uint>
1022
constexpr size_t bit_width = sizeof(Uint) * 8;
@@ -16,7 +28,7 @@ namespace cp_algo {
1628
size_t order_of_bit(auto x, size_t k) {
1729
return k ? std::popcount(x << (bit_width<decltype(x)> - k)) : 0;
1830
}
19-
[[gnu::target("bmi2")]] inline size_t kth_set_bit(uint64_t x, size_t k) {
31+
inline size_t kth_set_bit(uint64_t x, size_t k) {
2032
return std::countr_zero(_pdep_u64(1ULL << k, x));
2133
}
2234
template<int fl = 0>

cp-algo/util/simd.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cstdint>
55
#include <cstddef>
66
#include <memory>
7+
78
#if defined(__x86_64__) && !defined(CP_ALGO_DISABLE_AVX2)
89
#define CP_ALGO_SIMD_AVX2_TARGET _Pragma("GCC target(\"avx2\")")
910
#else
@@ -13,6 +14,7 @@
1314
#define CP_ALGO_SIMD_PRAGMA_PUSH \
1415
_Pragma("GCC push_options") \
1516
CP_ALGO_SIMD_AVX2_TARGET
17+
1618
CP_ALGO_SIMD_PRAGMA_PUSH
1719
namespace cp_algo {
1820
template<typename T, size_t len>

verify/structures/bitpack/det_mod_2.test.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
// @brief Determinant of Matrix (Mod 2)
33
#define PROBLEM "https://judge.yosupo.jp/problem/matrix_det_mod_2"
44
#pragma GCC optimize("O3,unroll-loops")
5-
#include "cp-algo/structures/bitpack.hpp"
5+
#include "cp-algo/structures/bit_array_util.hpp"
66
#include <bits/stdc++.h>
77

88
using namespace std;
9-
using cp_algo::structures::bitpack;
9+
using cp_algo::structures::bit_array;
1010

1111
const int maxn = 1 << 12;
12-
bitpack<maxn> a[maxn];
12+
bit_array<maxn> a[maxn];
1313

1414
void solve() {
1515
size_t n;
@@ -18,13 +18,13 @@ void solve() {
1818
vector<size_t> lead(n);
1919
for(size_t i = 0; i < n; i++) {
2020
cin >> row;
21-
a[i] = row;
21+
from_string(a[i], row);
2222
for(size_t j = 0; j < i; j++) {
2323
if(a[i][lead[j]]) {
2424
a[i].xor_hint(a[j], lead[j]);
2525
}
2626
}
27-
lead[i] = a[i].ctz();
27+
lead[i] = ctz(a[i]);
2828
if(lead[i] == n) {
2929
cout << 0 << "\n";
3030
return;

verify/structures/bitpack/inv_mod_2.test.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// @brief Inverse Matrix (Mod 2)
22
#define PROBLEM "https://judge.yosupo.jp/problem/inverse_matrix_mod_2"
33
#pragma GCC optimize("O3,unroll-loops")
4-
#include "cp-algo/structures/bitpack.hpp"
4+
#include "cp-algo/structures/bit_array_util.hpp"
55
#include <bits/stdc++.h>
66

77
using namespace std;
88
using namespace cp_algo::structures;
99

1010
const int maxn = 1 << 12;
11-
bitpack<2 * maxn> a[maxn];
11+
bit_array<2 * maxn> a[maxn];
1212

1313
void solve() {
1414
size_t n;
@@ -17,15 +17,15 @@ void solve() {
1717
vector<size_t> lead(n);
1818
for(size_t i = 0; i < n; i++) {
1919
cin >> row;
20-
a[i] = row;
20+
from_string(a[i], row);
2121
a[i].resize(2 * n);
2222
a[i].set(n + i);
2323
for(size_t j = 0; j < i; j++) {
2424
if(a[i][lead[j]]) {
2525
a[i].xor_hint(a[j], lead[j]);
2626
}
2727
}
28-
lead[i] = a[i].ctz();
28+
lead[i] = ctz(a[i]);
2929
if(lead[i] >= n) {
3030
cout << -1 << "\n";
3131
return;
@@ -41,7 +41,7 @@ void solve() {
4141
swap(a[i], a[lead[i]]);
4242
swap(lead[i], lead[lead[i]]);
4343
}
44-
cout << a[i].to_string().substr(n, n) << "\n";
44+
cout << to_string(a[i]).substr(n, n) << "\n";
4545
}
4646
}
4747

0 commit comments

Comments
 (0)