@@ -130,7 +130,7 @@ Matrix<T> power(Matrix<T> M, long long index) {
130130template <class T >
131131struct XORBasis {
132132 constexpr static T mx = std::numeric_limits<T>::max();
133- constexpr static int C = std::__lg(mx) ;
133+ constexpr static int C = std::numeric_limits<T>::digits ;
134134
135135 int siz = 0 ;
136136 std::array<T, C> p;
@@ -169,6 +169,7 @@ struct XORBasis {
169169 }
170170 }
171171 std::vector<T> narr;
172+ narr.reserve (siz);
172173 for (int i = 0 ; i < C; i++) {
173174 if (p[i] != 0 ) narr.push_back (p[i]);
174175 }
@@ -178,25 +179,32 @@ struct XORBasis {
178179 inline T kth (size_t k) { // kth minimum
179180 T ans = 0 ;
180181 assert (k >= 1 );
181- auto narr = rebuild ();
182- if (k > 1 || !has_zero) {
183- k -= has_zero;
184- assert (k < (1ull << siz));
185- for (int i = siz - 1 ; i >= 0 ; i--) {
186- if (k >> i & 1 ) ans ^= narr[i];
187- }
182+ auto narr = rebuild (); // narr[0] = smallest by MSB; narr[i] corresponds to bit i in k's binary (LSB -> narr[0])
183+ if (has_zero) {
184+ if (k == 1 ) return 0 ;
185+ else --k;
186+ }
187+ assert (k < (1ull << siz));
188+ // map bit i of k to narr[i] (LSB -> narr[0])
189+ for (int i = 0 ; i < siz; i++) {
190+ if ((k >> i) & 1ULL ) ans ^= narr[i];
188191 }
189192 return ans;
190193 }
191- inline size_t rank (T x) {
194+ inline size_t rank (T x) const {
192195 size_t ans = 0 ;
193- auto narr = rebuild ();
194- for (int i = siz - 1 ; i >= 0 ; i--) {
195- if (x >= narr[i]) {
196- ans |= 1ull << i, x ^= narr[i];
196+ auto narr = rebuild (); // narr ordered by increasing MSB
197+ for (int i = (int )narr.size () - 1 ; i >= 0 ; --i) {
198+ T b = narr[i];
199+ int hb = std::__lg (b);
200+ if (((x >> hb) & 1U ) != 0 ) {
201+ x ^= b;
202+ ans |= (1ULL << i);
197203 }
198204 }
199- return ans + has_zero;
205+ // after reduction, x should be 0 iff representable
206+ assert (x == 0 && " rank(x): x is not representable by this basis" );
207+ return ans + (has_zero ? 1ULL : 0ULL ); // 1-based
200208 }
201209};
202210
0 commit comments