This documentation is automatically generated by online-judge-tools/verification-helper
#include "setfunc/online/online_or_convolution.hpp"#include "setfunc/online/online_subset_zeta.hpp"
#include "setfunc/online/online_subset_mobius.hpp"
template <typename T>
struct Online_Or_Convolution {
Online_Subset_Zeta<T> X1, X2;
Online_Subset_Mobius<T> Y;
Online_Or_Convolution(int LOG) : X1(LOG), X2(LOG), Y(LOG) {}
// set a[i] and b[i], return conv(a,b)[i]
T set(int i, T ai, T bi) { return Y.set(i, X1.set(i, ai) * X2.set(i, bi)); }
// assume a[i],b[i], return zeta(a)[i]. not increment the pointer.
T assume(int i, T ai, T bi) {
return Y.assume(i, X1.assume(i, ai) * X2.assume(i, bi));
}
};#line 1 "enumerate/bits.hpp"
template <typename BS, typename F>
void enumerate_bits_bitset(BS& b, int L, int R, F&& f) {
if (L >= len(b)) return;
int p = (b[L] ? L : b._Find_next(L));
while (p < R) {
f(p);
p = b._Find_next(p);
}
}
template <typename UINT, typename F>
inline void enumerate_all_bit(UINT s, F&& f) {
static_assert(is_unsigned<UINT>::value);
while (s) {
f(lowbit(s));
s &= s - 1;
}
}
template <typename UINT, bool inc_empty, typename F>
inline void enumerate_all_subset(UINT s, F&& f) {
static_assert(is_unsigned<UINT>::value);
for (UINT t = s; t; t = (t - 1) & s) f(t);
if constexpr (inc_empty) f(0);
}
#line 2 "setfunc/online/online_subset_zeta.hpp"
/*
segtree を考える
現在のポインタの位置がある
もう全部の値が読まれた subtree ではゼータされた状態にしておく
*/
template <typename T>
struct Online_Subset_Zeta {
int n;
int p = 0;
vc<T> A;
Online_Subset_Zeta(int LOG) : n(LOG), A(1 << n) {}
// set a[i], return zeta(a)[i]
T set(int i, T a) {
assert(p == i);
T ans = assume(i, 0) + a;
A[p++] = a;
int K = lowbit(p);
for (int k = 0; k < K; ++k)
for (int j = p - (1 << k); j < p; ++j) A[j] += A[j - (1 << k)];
return ans;
}
// assume a[i], return zeta(a)[i]. not increment the pointer.
T assume(int i, T ai) {
assert(p == i);
T ans = ai;
enumerate_all_bit<u32>(i, [&](int j) -> void { ans += A[i - (1 << j)]; });
return ans;
}
};
#line 1 "enumerate/bits.hpp"
template <typename BS, typename F>
void enumerate_bits_bitset(BS& b, int L, int R, F&& f) {
if (L >= len(b)) return;
int p = (b[L] ? L : b._Find_next(L));
while (p < R) {
f(p);
p = b._Find_next(p);
}
}
template <typename UINT, typename F>
inline void enumerate_all_bit(UINT s, F&& f) {
static_assert(is_unsigned<UINT>::value);
while (s) {
f(lowbit(s));
s &= s - 1;
}
}
template <typename UINT, bool inc_empty, typename F>
inline void enumerate_all_subset(UINT s, F&& f) {
static_assert(is_unsigned<UINT>::value);
for (UINT t = s; t; t = (t - 1) & s) f(t);
if constexpr (inc_empty) f(0);
}
#line 2 "setfunc/online/online_subset_mobius.hpp"
template <typename T>
struct Online_Subset_Mobius {
int n;
int p = 0;
vc<T> A;
Online_Subset_Mobius(int LOG) : n(LOG), A(1 << n) {}
// set a[i], return zeta(a)[i]
T set(int i, T a) {
assert(p == i);
T ans = assume(i, 0) + a;
A[p++] = a;
int K = lowbit(p);
for (int k = 0; k < K; ++k)
for (int j = p - (1 << k); j < p; ++j) A[j] -= A[j - (1 << k)];
return ans;
}
// assume a[i], return zeta(a)[i]. not increment the pointer.
T assume(int i, T ai) {
assert(p == i);
T ans = ai;
enumerate_all_bit<u32>(i, [&](int j) -> vood { ans -= A[i - (1 << j)]; });
return ans;
}
};
#line 3 "setfunc/online/online_or_convolution.hpp"
template <typename T>
struct Online_Or_Convolution {
Online_Subset_Zeta<T> X1, X2;
Online_Subset_Mobius<T> Y;
Online_Or_Convolution(int LOG) : X1(LOG), X2(LOG), Y(LOG) {}
// set a[i] and b[i], return conv(a,b)[i]
T set(int i, T ai, T bi) { return Y.set(i, X1.set(i, ai) * X2.set(i, bi)); }
// assume a[i],b[i], return zeta(a)[i]. not increment the pointer.
T assume(int i, T ai, T bi) {
return Y.assume(i, X1.assume(i, ai) * X2.assume(i, bi));
}
};