// BEGIN: main.cpp #line 1 "main.cpp" // BEGIN: my_template.hpp #line 1 "my_template.hpp" #if defined(USE_PCH) #include #else #if defined(__GNUC__) #include #pragma GCC optimize("Ofast,unroll-loops") // 環境によってはコンパイル成功かつ実行時エラー #pragma GCC target("avx2,popcnt") #endif #include #include using namespace std; using ll = long long; using u8 = uint8_t; using u16 = uint16_t; using u32 = uint32_t; using u64 = uint64_t; using i128 = __int128; using u128 = unsigned __int128; using f128 = __float128; template constexpr bool dependent_false = false; template constexpr T infty = [] { static_assert(dependent_false, "infty is not defined"); return T{}; }(); template <> constexpr int infty = 1'010'000'000; template <> constexpr ll infty = 2'020'000'000'000'000'000; template <> constexpr u32 infty = infty; template <> constexpr u64 infty = infty; template <> constexpr i128 infty = i128(infty) * 2'000'000'000'000'000'000; template <> constexpr double infty = infty; template <> constexpr long double infty = infty; using pi = pair; using vi = vector; template using vc = vector; template using vvc = vector>; template using vvvc = vector>; template using vvvvc = vector>; template using pq_max = priority_queue; template using pq_min = priority_queue, greater>; #define vv(type, name, h, ...) \ vector> name(h, vector(__VA_ARGS__)) #define vvv(type, name, h, w, ...) \ vector>> name( \ h, vector>(w, vector(__VA_ARGS__))) #define vvvv(type, name, a, b, c, ...) \ vector>>> name( \ a, vector>>( \ b, vector>(c, vector(__VA_ARGS__)))) // https://trap.jp/post/1224/ #define FOR1(a) for (ll _ = 0; _ < ll(a); ++_) #define FOR2(i, a) for (ll i = 0; i < ll(a); ++i) #define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i) #define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c)) #define FOR1_R(a) for (ll i = ll(a) - 1; i >= ll(0); --i) #define FOR2_R(i, a) for (ll i = ll(a) - 1; i >= ll(0); --i) #define FOR3_R(i, a, b) for (ll i = ll(b) - 1; i >= ll(a); --i) #define overload4(a, b, c, d, e, ...) e #define overload3(a, b, c, d, ...) d #define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__) #define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__) #define all(x) (x).begin(), (x).end() #define len(x) ll(x.size()) #define elif else if #define eb emplace_back #define mp make_pair #define mt make_tuple #define fi first #define se second #define stoi stoll // require y > 0 template T floor(T x, T y) { return x / y - (x % y < 0); } // require y > 0 template T ceil(T x, T y) { return (x / y) + (x % y > 0); } // require y > 0 template T bmod(T x, T y) { T r = x % y; return (r < 0 ? r + y : r); } // require y > 0 template pair divmod(T x, T y) { T q = x / y, r = x % y; if (r < 0) --q, r += y; return {q, r}; } constexpr auto TEN = [] { array A{}; A[0] = 1; for (int i = 1; i < 20; ++i) A[i] = 10 * A[i - 1]; return A; }(); template T SUM(const U &A) { return std::accumulate(A.begin(), A.end(), T{}); } #define MIN(v) *min_element(all(v)) #define MAX(v) *max_element(all(v)) template inline long long LB(const C &c, const T &x) { return lower_bound(c.begin(), c.end(), x) - c.begin(); } template inline long long UB(const C &c, const T &x) { return upper_bound(c.begin(), c.end(), x) - c.begin(); } #define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()) template T POP(deque &que) { T a = que.front(); que.pop_front(); return a; } template T POP(priority_queue &que) { T a = que.top(); que.pop(); return a; } template T POP(vc &que) { T a = que.back(); que.pop_back(); return a; } template i128 binary_search(F check, i128 ok, i128 ng, bool check_ok = true) { if (check_ok) assert(check(ok)); while (1) { i128 x = (ok + ng) / 2; if (x == ok || x == ng) break; (check(x) ? ok : ng) = x; } return ok; } template double binary_search_real(F check, double ok, double ng, int iter = 100) { FOR(iter) { double x = (ok + ng) / 2; (check(x) ? ok : ng) = x; } return (ok + ng) / 2; } template inline bool chmax(T &a, const S &b) { T c = max(a, b); bool changed = (c != a); a = c; return changed; } template inline bool chmin(T &a, const S &b) { T c = min(a, b); bool changed = (c != a); a = c; return changed; } // ? は -1 vc s_to_vi(const string &S, char first_char) { vc A(S.size()); FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); } return A; } template vc cumsum(const vc &A, int off = 1) { int N = A.size(); vc B(N + 1); FOR(i, N) { B[i + 1] = B[i] + A[i]; } if (off == 0) B.erase(B.begin()); return B; } // stable sort template vc argsort(const vc &A) { vc ids(len(A)); iota(all(ids), 0); sort(all(ids), [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); }); return ids; } // A[I[0]], A[I[1]], ... template vc rearrange(const vc &A, const vc &I) { vc B(len(I)); FOR(i, len(I)) B[i] = A[I[i]]; return B; } template void concat(vc &first, const Vectors &...others) { first.reserve(first.size() + (others.size() + ... + 0)); (first.insert(first.end(), others.begin(), others.end()), ...); } // i128 template , int> = 0> constexpr i128 abs(T x) { return x < 0 ? -x : x; } constexpr i128 gcd(i128 a, i128 b) { while (b != 0) { i128 c = a % b; a = b, b = c; } return abs(a); } #endif // END: my_template.hpp #line 2 "main.cpp" // BEGIN: other/io.hpp #line 1 "other/io.hpp" #define FASTIO // https://judge.yosupo.jp/submission/21623 namespace fastio { static constexpr uint32_t SZ = 1 << 17; char ibuf[SZ]; char obuf[SZ]; char out[100]; // pointer of ibuf, obuf uint32_t pil = 0, pir = 0, por = 0; bool input_eof = false; template constexpr bool is_signed_integer_v = is_signed_v || is_same_v; template struct unsigned_integer { using type = make_unsigned_t; }; template <> struct unsigned_integer { using type = u128; }; template <> struct unsigned_integer { using type = u128; }; template using unsigned_integer_t = typename unsigned_integer::type; [[noreturn]] inline void input_error(const char *message) { fputs(message, stderr); fputc('\n', stderr); exit(EXIT_FAILURE); } struct Pre { char num[10000][4]; constexpr Pre() : num() { for (int i = 0; i < 10000; i++) { int n = i; for (int j = 3; j >= 0; j--) { num[i][j] = n % 10 | '0'; n /= 10; } } } } constexpr pre; inline void load() { uint32_t n = pir - pil; memmove(ibuf, ibuf + pil, n); pil = 0; pir = n; if (input_eof) return; pir += fread(ibuf + pir, 1, SZ - pir, stdin); if (ferror(stdin)) input_error("fastio: input error"); if (feof(stdin)) { input_eof = true; // Allows the last token to end exactly at EOF without a trailing // whitespace. if (pir < SZ) ibuf[pir++] = '\n'; } } inline char get_char() { if (pil == pir) { load(); if (pil == pir) input_error("fastio: unexpected EOF"); } return ibuf[pil++]; } inline void flush() { fwrite(obuf, 1, por, stdout); por = 0; } void rd(char &c) { do c = get_char(); while (isspace(static_cast(c))); } void rd(string &x) { x.clear(); char c; do c = get_char(); while (isspace(static_cast(c))); do { x += c; c = get_char(); } while (!isspace(static_cast(c))); } template void rd_real(T &x) { string s; rd(s); x = stod(s); } template void rd_integer_slow(T &x) { char c; do c = get_char(); while (c < '-'); bool minus = 0; if constexpr (is_signed_integer_v) { if (c == '-') { minus = 1, c = get_char(); } } x = 0; assert('0' <= c && c <= '9'); while ('0' <= c && c <= '9') { x = x * 10 + (c & 15), c = get_char(); } assert(isspace(static_cast(c))); if constexpr (is_signed_integer_v) { if (minus) x = -x; } } template void rd_integer(T &x) { if (pil + 100 > pir) { load(); if (pil + 100 > pir) { rd_integer_slow(x); return; } } char c; do c = ibuf[pil++]; while (c < '-'); bool minus = 0; if constexpr (is_signed_integer_v) { if (c == '-') { minus = 1, c = ibuf[pil++]; } } x = 0; assert('0' <= c && c <= '9'); while ('0' <= c && c <= '9') { x = x * 10 + (c & 15), c = ibuf[pil++]; } assert(isspace(static_cast(c))); if constexpr (is_signed_integer_v) { if (minus) x = -x; } } template enable_if_t || is_same_v || is_same_v> rd( T &x) { rd_integer(x); } template enable_if_t || is_same_v> rd(T &x) { rd_real(x); } template void rd(pair &p) { rd(p.first), rd(p.second); } template void rd_tuple(T &t) { if constexpr (N < tuple_size::value) { auto &x = get(t); rd(x); rd_tuple(t); } } template void rd(tuple &tpl) { rd_tuple(tpl); } template void rd(array &x) { for (auto &d : x) rd(d); } template void rd(vc &x) { for (auto &d : x) rd(d); } template void read(T &...x) { (rd(x), ...); } inline void wt_range(const char *s, size_t n) { size_t i = 0; while (i < n) { if (por == SZ) flush(); size_t chunk = min(n - i, (size_t)(SZ - por)); memcpy(obuf + por, s + i, chunk); por += chunk; i += chunk; } } void wt(const char c) { if (por == SZ) flush(); obuf[por++] = c; } void wt(const char *s) { wt_range(s, strlen(s)); } void wt(const string &s) { wt_range(s.data(), s.size()); } template void wt_integer(T x) { if (por > SZ - 100) flush(); using U = unsigned_integer_t; U y = static_cast(x); if constexpr (is_signed_integer_v) { if (x < 0) { obuf[por++] = '-'; y = U(0) - y; } } int outi; for (outi = 96; y >= 10000; outi -= 4) { memcpy(out + outi, pre.num[y % 10000], 4); y /= 10000; } if (y >= 1000) { memcpy(obuf + por, pre.num[y], 4); por += 4; } else if (y >= 100) { memcpy(obuf + por, pre.num[y] + 1, 3); por += 3; } else if (y >= 10) { int q = (y * 103) >> 10; obuf[por] = q | '0'; obuf[por + 1] = (y - q * 10) | '0'; por += 2; } else obuf[por++] = y | '0'; memcpy(obuf + por, out + outi + 4, 96 - outi); por += 96 - outi; } template inline void wt_real(T x) { static char buf[1000]; int n = std::snprintf(buf, sizeof(buf), "%.15f", (double)x); wt_range(buf, (size_t)n); } template enable_if_t || is_same_v || is_same_v> wt( T x) { wt_integer(x); } template enable_if_t || is_same_v> wt(T x) { wt_real(x); } inline void wt(bool b) { wt(static_cast('0' + (b ? 1 : 0))); } template void wt(const pair &val) { wt(val.first); wt(' '); wt(val.second); } template void wt_tuple(const T &t) { if constexpr (N < tuple_size::value) { if constexpr (N > 0) wt(' '); wt(get(t)); wt_tuple(t); } } template void wt(const tuple &tpl) { wt_tuple(tpl); } template void wt(const array &val) { auto n = val.size(); for (size_t i = 0; i < n; i++) { if (i) wt(' '); wt(val[i]); } } template void wt(const vector &val) { auto n = val.size(); for (size_t i = 0; i < n; i++) { if (i) wt(' '); wt(val[i]); } } void print() { wt('\n'); } template void print(Head &&head, Tail &&...tail) { wt(forward(head)); ((wt(' '), wt(forward(tail))), ...); wt('\n'); } // gcc expansion. called automaticall after main. void __attribute__((destructor)) _d() { flush(); } } // namespace fastio using fastio::flush; using fastio::print; using fastio::read; #if defined(LOCAL) #define HDR "[DEBUG:", __func__, __LINE__, "]" #define SHOW(...) \ SHOW_IMPL(__VA_ARGS__, SHOW8, SHOW7, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, \ SHOW1) \ (__VA_ARGS__) #define SHOW_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME #define SHOW1(x) print(HDR, #x, "=", (x)), flush() #define SHOW2(x, y) print(HDR, #x, "=", (x), #y, "=", (y)), flush() #define SHOW3(x, y, z) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z)), flush() #define SHOW4(x, y, z, w) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush() #define SHOW5(x, y, z, w, v) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v)), \ flush() #define SHOW6(x, y, z, w, v, u) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v), #u, "=", (u)), \ flush() #define SHOW7(x, y, z, w, v, u, t) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v), #u, "=", (u), #t, "=", (t)), \ flush() #define SHOW8(x, y, z, w, v, u, t, s) \ print(HDR, #x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", \ (v), #u, "=", (u), #t, "=", (t), #s, "=", (s)), \ flush() #else #define SHOW(...) #endif #define INT(...) \ int __VA_ARGS__; \ read(__VA_ARGS__) #define LL(...) \ ll __VA_ARGS__; \ read(__VA_ARGS__) #define U32(...) \ u32 __VA_ARGS__; \ read(__VA_ARGS__) #define U64(...) \ u64 __VA_ARGS__; \ read(__VA_ARGS__) #define STR(...) \ string __VA_ARGS__; \ read(__VA_ARGS__) #define CHAR(...) \ char __VA_ARGS__; \ read(__VA_ARGS__) #define DBL(...) \ double __VA_ARGS__; \ read(__VA_ARGS__) #define VEC(type, name, size) \ vector name(size); \ read(name) #define VV(type, name, h, w) \ vector> name(h, vector(w)); \ read(name) void YES(bool t = 1) { print(t ? "YES" : "NO"); } void NO(bool t = 1) { YES(!t); } void Yes(bool t = 1) { print(t ? "Yes" : "No"); } void No(bool t = 1) { Yes(!t); } void yes(bool t = 1) { print(t ? "yes" : "no"); } void no(bool t = 1) { yes(!t); } void YA(bool t = 1) { print(t ? "YA" : "TIDAK"); } void TIDAK(bool t = 1) { YA(!t); } void Alice(bool t = 1) { print(t ? "Alice" : "Bob"); } void Bob(bool t = 1) { Alice(!t); }// END: other/io.hpp #line 3 "main.cpp" // BEGIN: ds/bit_array.hpp #line 1 "ds/bit_array.hpp" #line 2 "ds/bit_array.hpp" #line 3 "ds/bit_array.hpp" // BEGIN: other/bit.hpp #line 1 "other/bit.hpp" int popcnt(int x) { return __builtin_popcount(x); } int popcnt(u32 x) { return __builtin_popcount(x); } int popcnt(ll x) { return __builtin_popcountll(x); } int popcnt(u64 x) { return __builtin_popcountll(x); } int popcnt_sgn(int x) { return (__builtin_parity(unsigned(x)) & 1 ? -1 : 1); } int popcnt_sgn(u32 x) { return (__builtin_parity(x) & 1 ? -1 : 1); } int popcnt_sgn(ll x) { return (__builtin_parityll(x) & 1 ? -1 : 1); } int popcnt_sgn(u64 x) { return (__builtin_parityll(x) & 1 ? -1 : 1); } // (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2) int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); } int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); } int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } // (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2) int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); } int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); } int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } template T kth_bit(int k) { assert(0 <= k && k < int(8 * sizeof(T))); return T(1) << k; } template bool has_kth_bit(T x, int k) { assert(0 <= k && k < int(8 * sizeof(T))); return x >> k & 1; } template struct all_bit { static_assert(is_unsigned::value); UINT s; all_bit(UINT s) : s(s) {} struct iter { UINT s; int operator*() const { return lowbit(s); } void operator++() { s &= s - 1; } bool operator!=(nullptr_t) const { return s; } }; iter begin() const { return {s}; } nullptr_t end() const { return nullptr; } }; template struct all_subset { static_assert(is_unsigned::value); UINT s; all_subset(UINT s) : s(s) {} struct iter { UINT s, t; bool done = false; UINT operator*() const { return t; } void operator++() { done = (t == 0); t = (t - 1) & s; } bool operator!=(nullptr_t) const { return !done; } }; iter begin() const { return {s, s}; } nullptr_t end() const { return nullptr; } }; constexpr u64 full_mask(int n) { assert(0 <= n && n <= 64); return n == 64 ? -1ULL : (1ULL << n) - 1; } u64 bit_reverse(u64 x) { x = ((x & 0x5555555555555555ULL) << 1) | ((x >> 1) & 0x5555555555555555ULL); x = ((x & 0x3333333333333333ULL) << 2) | ((x >> 2) & 0x3333333333333333ULL); x = ((x & 0x0f0f0f0f0f0f0f0fULL) << 4) | ((x >> 4) & 0x0f0f0f0f0f0f0f0fULL); x = ((x & 0x00ff00ff00ff00ffULL) << 8) | ((x >> 8) & 0x00ff00ff00ff00ffULL); x = ((x & 0x0000ffff0000ffffULL) << 16) | ((x >> 16) & 0x0000ffff0000ffffULL); x = (x << 32) | (x >> 32); return x; }// END: other/bit.hpp #line 5 "ds/bit_array.hpp" /* 01 列を管理する.内部では 64 bit ごとにまとめて保持する.主な用途として, - 可変長でスライス操作が可能な bitset - F_2 上の多項式 などを想定している. */ struct Bit_Array { using T = Bit_Array; int N; vc dat; // x で埋める Bit_Array(int N = 0, int x = 0) : N(N) { assert(N >= 0); assert(x == 0 || x == 1); u64 v = (x == 0 ? 0 : -1); dat.assign((N + 63) >> 6, v); resize(N); } int size() const { return N; } void resize(int n) { assert(n >= 0); dat.resize((n + 63) >> 6); int r = n & 63; if (r) dat.back() &= full_mask(r); N = n; } void fill0() { fill(all(dat), u64(0)); } void fill1() { fill(all(dat), u64(-1)); resize(N); } void push_back(bool b) { resize(N + 1); (*this)[N - 1] = b; } static T from_string(const string &S) { int N = len(S); T ANS(N); FOR(i, N) ANS[i] = (S[i] == '1'); return ANS; } class Proxy { public: Proxy(vc &d, int i) : dat(d), index(i) {} operator bool() const { return (dat[index >> 6] >> (index & 63)) & 1; } Proxy &operator=(bool value) { u64 mask = u64(1) << (index & 63); if (value) dat[index >> 6] |= mask; else dat[index >> 6] &= ~mask; return *this; } Proxy &operator=(const Proxy &p) { return *this = bool(p); } // bit operations Proxy &operator^=(bool x) { if (x) dat[index >> 6] ^= u64(1) << (index & 63); return *this; } Proxy &operator|=(bool x) { if (x) dat[index >> 6] |= u64(1) << (index & 63); return *this; } Proxy &operator&=(bool x) { if (!x) dat[index >> 6] &= ~(u64(1) << (index & 63)); return *this; } // finite field F_2 Proxy &operator+=(bool x) { return *this ^= x; } Proxy &operator-=(bool x) { return *this ^= x; } Proxy &operator*=(bool x) { return *this &= x; } Proxy &operator/=(bool x) { assert(x); return *this; } bool inverse() const { assert(bool(*this)); return true; } void flip() { *this ^= true; } private: vc &dat; int index; }; Proxy operator[](int i) { assert(0 <= i && i < N); return Proxy(dat, i); } bool operator[](int i) const { assert(0 <= i && i < N); return (dat[i >> 6] >> (i & 63)) & 1; } bool operator==(const T &p) const { if (N != p.N) return false; FOR(i, len(dat)) if (dat[i] != p.dat[i]) return false; return true; } T &operator&=(const T &p) { assert(N == p.N); FOR(i, len(dat)) dat[i] &= p.dat[i]; return *this; } T &operator|=(const T &p) { assert(N == p.N); FOR(i, len(dat)) dat[i] |= p.dat[i]; return *this; } T &operator^=(const T &p) { assert(N == p.N); FOR(i, len(dat)) dat[i] ^= p.dat[i]; return *this; } T operator&(const T &p) const { return T(*this) &= p; } T operator|(const T &p) const { return T(*this) |= p; } T operator^(const T &p) const { return T(*this) ^= p; } T operator~() const { T p = (*this); p.flip_range(0, N); return p; } void set_minus_inplace(const T &other) { assert(N == other.N); FOR(i, len(dat)) dat[i] = dat[i] & (~other.dat[i]); } T set_minus(T other) const { assert(N == other.N); FOR(i, len(dat)) other.dat[i] = dat[i] & ~other.dat[i]; return other; } int count() const { int ans = 0; for (u64 val : dat) ans += popcnt(val); return ans; } // size of set intersection, not modulo 2 int dot(const T &p) const { assert(N == p.N); int ans = 0; FOR(i, len(dat)) ans += popcnt(dat[i] & p.dat[i]); return ans; } // minimum j >= i with (*this)[j] = 1, or N if none int next(int i) const { chmax(i, 0); if (i >= N) return N; int k = i >> 6; { u64 x = dat[k]; int s = i & 63; x = (x >> s) << s; if (x) return (k << 6) | lowbit(x); } FOR(idx, k + 1, len(dat)) { if (dat[idx] == 0) continue; return (idx << 6) | lowbit(dat[idx]); } return N; } // maximum j <= i with (*this)[j] = 1, or -1 if none int prev(int i) const { chmin(i, N - 1); if (i <= -1) return -1; int k = i >> 6; if ((i & 63) < 63) { u64 x = dat[k]; x &= (u64(1) << ((i & 63) + 1)) - 1; if (x) return (k << 6) | topbit(x); --k; } FOR_R(idx, k + 1) { if (dat[idx] == 0) continue; return (idx << 6) | topbit(dat[idx]); } return -1; } Bit_Array slice(int L, int R) const { assert(0 <= L && L <= R && R <= N); Bit_Array p(R - L); int rm = (R - L) & 63; FOR(rm) { p[R - L - 1] = bool((*this)[R - 1]); --R; } int n = (R - L) >> 6; int hi = L & 63; int lo = 64 - hi; int s = L >> 6; if (hi == 0) { FOR(i, n) { p.dat[i] = dat[s + i]; } } else { FOR(i, n) { p.dat[i] = (dat[s + i] >> hi) | (dat[s + i + 1] << lo); } } return p; } int count_range(int L, int R) const { assert(0 <= L && L <= R && R <= N); int cnt = 0; while ((L < R) && (L & 63)) cnt += (*this)[L++]; while ((L < R) && (R & 63)) cnt += (*this)[--R]; int l = L >> 6, r = R >> 6; FOR(i, l, r) cnt += popcnt(dat[i]); return cnt; } // [L,R) に p を代入 void assign_to_range(int L, int R, const Bit_Array &p) { assert(0 <= L && L <= R && R <= N); assert(p.N == R - L); int a = 0, b = p.N; while (L < R && (L & 63)) { (*this)[L++] = bool(p[a++]); } while (L < R && (R & 63)) { (*this)[--R] = bool(p[--b]); } // p[a:b] を [L:R] に int l = L >> 6, r = R >> 6; int s = a >> 6; int n = r - l; if (!(a & 63)) { FOR(i, n) dat[l + i] = p.dat[s + i]; } else { int hi = a & 63; int lo = 64 - hi; FOR(i, n) dat[l + i] = (p.dat[s + i] >> hi) | (p.dat[1 + s + i] << lo); } } // [L,R) に p を xor void xor_to_range(int L, int R, const Bit_Array &p) { assert(0 <= L && L <= R && R <= N); assert(p.N == R - L); int a = 0, b = p.N; while (L < R && (L & 63)) { dat[L >> 6] ^= u64(p[a]) << (L & 63); ++a, ++L; } while (L < R && (R & 63)) { --b, --R; dat[R >> 6] ^= u64(p[b]) << (R & 63); } // p[a:b] を [L:R] に int l = L >> 6, r = R >> 6; int s = a >> 6; int n = r - l; if (!(a & 63)) { FOR(i, n) dat[l + i] ^= p.dat[s + i]; } else { int hi = a & 63; int lo = 64 - hi; FOR(i, n) dat[l + i] ^= (p.dat[s + i] >> hi) | (p.dat[1 + s + i] << lo); } } // [L,R) に p を and void and_to_range(int L, int R, const Bit_Array &p) { assert(0 <= L && L <= R && R <= N); assert(p.N == R - L); int a = 0, b = p.N; while (L < R && (L & 63)) { if (!p[a]) (*this)[L] = 0; a++, L++; } while (L < R && (R & 63)) { --b, --R; if (!p[b]) (*this)[R] = 0; } // p[a:b] を [L:R] に int l = L >> 6, r = R >> 6; int s = a >> 6; int n = r - l; if (!(a & 63)) { FOR(i, n) dat[l + i] &= p.dat[s + i]; } else { int hi = a & 63; int lo = 64 - hi; FOR(i, n) dat[l + i] &= (p.dat[s + i] >> hi) | (p.dat[1 + s + i] << lo); } } // [L,R) に p を or void or_to_range(int L, int R, const Bit_Array &p) { assert(0 <= L && L <= R && R <= N); assert(p.N == R - L); int a = 0, b = p.N; while (L < R && (L & 63)) { dat[L >> 6] |= u64(p[a]) << (L & 63); ++a, ++L; } while (L < R && (R & 63)) { --b, --R; dat[R >> 6] |= u64(p[b]) << (R & 63); } // p[a:b] を [L:R] に int l = L >> 6, r = R >> 6; int s = a >> 6; int n = r - l; if (!(a & 63)) { FOR(i, n) dat[l + i] |= p.dat[s + i]; } else { int hi = a & 63; int lo = 64 - hi; FOR(i, n) dat[l + i] |= (p.dat[s + i] >> hi) | (p.dat[1 + s + i] << lo); } } // p は [i:N) にしかないとして p を xor する // 行列基本変形などで利用可能 void xor_suffix(int i, const Bit_Array &p) { assert(N == p.N && 0 <= i && i < N); FOR(k, i / 64, len(dat)) { dat[k] ^= p.dat[k]; } } // [L,R) を 1 に変更 void set_range(int L, int R) { assert(0 <= L && L <= R && R <= N); while (L < R && (L & 63)) set(L++); while (L < R && (R & 63)) set(--R); FOR(i, L >> 6, R >> 6) dat[i] = u64(-1); } // [L,R) を 0 に変更 void reset_range(int L, int R) { assert(0 <= L && L <= R && R <= N); while (L < R && (L & 63)) reset(L++); while (L < R && (R & 63)) reset(--R); FOR(i, L >> 6, R >> 6) dat[i] = u64(0); } // [L,R) を flip void flip_range(int L, int R) { assert(0 <= L && L <= R && R <= N); while (L < R && (L & 63)) flip(L++); while (L < R && (R & 63)) flip(--R); FOR(i, L >> 6, R >> 6) dat[i] ^= u64(-1); } // bitset に仕様を合わせる void set(int i) { (*this)[i] = 1; } void reset(int i) { (*this)[i] = 0; } void flip(int i) { (*this)[i].flip(); } void set() { set_range(0, N); } void reset() { reset_range(0, N); } void flip() { flip_range(0, N); } bool any() const { FOR(i, len(dat)) { if (dat[i]) return true; } return false; } bool has_intersection(const T &other) const { assert(N == other.N); FOR(i, len(dat)) if (dat[i] & other.dat[i]) return true; return false; } template void enumerate_intersection(const T &other, F f) const { assert(N == other.N); bool end = false; FOR(i, len(dat)) { u64 x = dat[i] & other.dat[i]; while (x) { int k = lowbit(x); f(64 * i + k, end); if (end) return; x &= x - 1; } } } bool ALL() const { int r = N & 63; if (r != 0 && dat.back() != full_mask(r)) return 0; for (int i = 0; i < N / 64; ++i) if (dat[i] != u64(-1)) return false; return true; } Bit_Array reversed() const { int M = ceil(N, 64) * 64; Bit_Array a = *this; a.resize(M); reverse(all(a.dat)); for (u64 &x : a.dat) x = bit_reverse(x); return a.slice(M - N, M); } // bs[i]==true であるような i 全体 vc collect_idx() const { vc I; FOR(i, N) if ((*this)[i]) I.eb(i); return I; } bool is_subset(const T &other) const { assert(other.N == N); FOR(i, len(dat)) { u64 a = dat[i], b = other.dat[i]; if ((a & b) != a) return false; } return true; } int _Find_first() const { return next(0); } int _Find_next(int p) const { return next(p + 1); } template void enumerate(int L, int R, F f) const { assert(0 <= L && L <= R && R <= N); if (L == R) return; int p = ((*this)[L] ? L : _Find_next(L)); while (p < R) { f(p); p = _Find_next(p); } } inline static string TO_STR[256]; string to_string() const { if (TO_STR[0].empty()) precompute(); string S; for (u64 x : dat) { FOR(i, 8) S += TO_STR[(x >> (8 * i) & 255)]; } S.resize(N); return S; } static void precompute() { FOR(s, 256) { string x; FOR(i, 8) x += '0' + (s >> i & 1); TO_STR[s] = x; } } void prefix_xor_sum() { int carry = 0; for (u64 &a : dat) { a ^= carry; carry = __builtin_parityll(a); a ^= a << (1 << 0); a ^= a << (1 << 1); a ^= a << (1 << 2); a ^= a << (1 << 3); a ^= a << (1 << 4); a ^= a << (1 << 5); } resize(N); } };// END: ds/bit_array.hpp #line 5 "main.cpp" using BS = Bit_Array; void solve() { LL(N, S); BS dp(S + 1); dp[0] = 1; FOR(N) { INT(a); if (a > S) continue; BS x = dp.slice(0, S - a + 1); dp.or_to_range(a, S + 1, x); } int ANS = dp.prev(S); print(ANS); } signed main() { INT(T); FOR(T) solve(); } // END: main.cpp