void fwt(ll *a, int op)
{
for (int cnt_pre = 1, cnt_cur = 2; cnt_pre < tot; cnt_pre <<= 1, cnt_cur <<= 1)
for (int i = 0; i < tot; i += cnt_cur)
for (int j = 0; j < cnt_pre; j++)
{
if(op == 1) (a[i + j + cnt_pre] += a[i + j]) %= mod; //or
else if(op == 2) (a[i + j] += a[i + j + cnt_pre]) %= mod; //and
else if(op == 3) //xor
{
ll k = a[i + j];
(a[i + j] += a[i + j + cnt_pre]) %= mod;
(a[i + j + cnt_pre] -= k - mod) %= mod;
}
}
}
void ufwt(ll *a, int op)
{
for (int cnt_pre = tot >> 1, cnt_cur = tot; cnt_pre > 0; cnt_pre >>= 1, cnt_cur >>= 1)
for (int i = 0; i < tot; i += cnt_cur)
for (int j = 0; j < cnt_pre; j++)
{
if(op == 1) (a[i + j + cnt_pre] -= a[i + j] - mod) %= mod; //or
else if(op == 2) (a[i + j] -= a[i + j + cnt_pre] - mod) %= mod; //and
else if(op == 3)//xor
{
ll k = a[i + j];
a[i + j] = (a[i + j] + a[i + j + cnt_pre]) * mod_inv_2 % mod;
a[i + j + cnt_pre] = (k - a[i + j + cnt_pre] + mod) * mod_inv_2 % mod;
}
}
}
void slove(ll *a,ll *b,int op)
{
fwt(a,op);fwt(b,op);
for (int j = 0; j < tot; j++)
a[j] = a[j] * b[j] % mod;
ufwt(a,op);//结果在a[i]中
}