struct SegBase
{
using ll = long long;
bool zero; // 判断线性基中有无0出现
// maxsiz = log2(值域上边界)
#define maxsiz 64
vector<ll> segbase; // 线性基本身
vector<ll> newbase; // 重构后的线性基
// 初始化线性基大小
SegBase(int n = maxsiz)
{
segbase = vector<ll>(n);
}
// 构建线性基
void insert(ll x)
{
if(x == 0) return ;
int k = log2(x);
if(!segbase[k]) return segbase[k] = x, void();
insert(segbase[k] ^ x);
}
// 查询一个元素是否可以被异或出来
int ask(ll x)
{
for(int i = maxsiz - 1; i >= 0; i--)
if(x >> i & 1) x ^= segbase[i];
return x == 0;
}
// 查询异或最大值
ll askmax()
{
ll res = 0;
for(int i =maxsiz - 1; i >= 0; i--)
if(res ^ segbase[i] > res) res ^= segbase[i];
return res;
}
// 查询异或最小值,(一般来说就是线性基里的最小元素)
ll askmin()
{
if(zero) return 0;
for(int i = 0; i < maxsiz; i++)
if(segbase[i]) return segbase[i];
}
// 查询异或第k小
void rebuild()
{// 重构线性基使得segbase[i]只留下第i位的1,使得他们互不影响
int cnt = 0, top = 0;
for(int i = maxsiz - 1; i >= 0; i--)
{
for(int j = i - 1; j >= 0; j--)
{
if(segbase[i] >> j & 1)
segbase[i] ^= segbase[j];
}
}
for(int i = 0; i < maxsiz; i++)
if(segbase[i])
newbase.push_back(segbase[i]);
}
ll kth(int k)
{// 互不影响之后就可以根据k的二进制选值了,注意线性基是否含0
if(k >= (1 << newbase.size())) return -1;
ll res = 0;
for(int i = maxsiz - 1; i >= 0; i--)
if(k >> i & 1)
res ^= newbase[i];
}
int rank(ll x)
{// kth函数的逆操作
int res = 0;
for(int i = maxsiz - 1; i >= 0; i--)
if(x >= newbase[i])
res |= 1 << i,
x ^= newbase[i];
return res;
}
} ;