如题,WA on #5,原因不明。
// clang-format off
#include <bits/stdc++.h>
using namespace std;
#if __cplusplus < 201400
#warning "Please use c++14 or higher."
#define INLINE_V
#define REGISTER_V register
#define CPP14CONSTEXPR
#define gcd __gcd
#define CPP14ENABLE_IF
#elif __cplusplus < 201700
#define INLINE_V
#define REGISTER_V
#define CPP14CONSTEXPR constexpr
#define gcd __gcd
#define CPP14ENABLE_IF ,enable_if_t<_is_integer<T>, int> = 0
#else
#define INLINE_V inline
#define REGISTER_V
#define CPP14CONSTEXPR constexpr
#define CPP14ENABLE_IF ,enable_if_t<_is_integer<T>, int> = 0
#endif
#if !defined(_WIN32) && !defined(LOCK_GETCHAR)
#define getchar getchar_unlocked
#endif
#define il inline
#define mkp make_pair
#define fi first
#define se second
#define For(i,j,k) for(REGISTER_V int i=(j);i<=(k);++i) // NOLINT
#define ForDown(i,j,k) for(REGISTER_V int i=(j);i>=(k);--i) // NOLINT
#define pb push_back
#define eb emplace_back
#ifndef ONLINE_JUDGE
#define FileIO(filename) freopen(filename".in","r",stdin);freopen(filename".out","w",stdout)
#else
#define FileIO(filename)
#endif
using ll = long long;
// using lll = __int128_t;
using uint = unsigned int;
using ull = unsigned long long;
// using ulll = __uint128_t;
using db = double;
using ldb = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#if __cplusplus >= 201400
template <class T> INLINE_V constexpr bool _is_integer = numeric_limits<T>::is_integer;
// template <> INLINE_V constexpr bool _is_integer<__int128> = true;
// template <> INLINE_V constexpr bool _is_integer<__uint128_t> = true;
template <> INLINE_V constexpr bool _is_integer<bool> = false;
template <> INLINE_V constexpr bool _is_integer<char> = false;
template <class T CPP14ENABLE_IF>
INLINE_V constexpr T INF = numeric_limits<T>::max() >> 1;
#endif
template<typename T> constexpr il T sq(const T & x){return x*x;}
template<typename T> CPP14CONSTEXPR il void cmin(T & x, const T &y){x=min(x,y);}
template<typename T> CPP14CONSTEXPR il void cmax(T & x, const T &y){x=max(x,y);}
template<typename T> CPP14CONSTEXPR il T qpow(T x, ull y, T mod){T ans=1;x%=mod;while(y){if(y&1)(ans*=x)%=mod;(x*=x)%=mod;y>>=1;}return ans;}
template<typename T> CPP14CONSTEXPR il T qpow(T x, ull y){T ans=1;while(y){if(y&1)ans*=x;x*=x;y>>=1;}return ans;}
template<typename T CPP14ENABLE_IF> il void read(T &x){ x=0;int f=1;int c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;}
template<typename T, typename ... Args> il void read(T &x, Args &... y){ read(x);read(y...); }
// File head end
// clang-format on
namespace {
#define int ll
constexpr ll MAXN = 2e5 + 5, mod = 998244353;
ll T, n, k, a[MAXN], b[MAXN], bit[MAXN];
#define lowbit(x) (x & -x)
il void upd(int pos, int val) {
while (pos <= k)
bit[pos] += val, pos += lowbit(pos);
}
il ll qry(int pos) {
ll __ans = 0;
while (pos)
__ans += bit[pos], pos -= lowbit(pos);
return __ans;
}
il ll calc_B() {
fill(bit + 1, bit + 1 + k, 0);
ll __ans = 0;
For(i, 1, k) {
(__ans += qry(k - b[i])) %= mod;
upd(k - b[i], 1);
}
return __ans;
}
namespace FHQ {
constexpr ll MAXN = 4e5 + 5;
static mt19937 rnd{random_device{}()};
struct Node {
int lc, rc, cnt, sz, val;
uint prio;
Node() : lc(0), rc(0), cnt(0), sz(0), val(0), prio(rnd()) {}
} static T[MAXN];
static vector<int> trash;
static int cnt = 0;
il int newNode() {
int p;
if (trash.empty())
p = ++cnt;
else
p = trash.back(), trash.pop_back();
return T[p] = {}, p;
}
il void delNode(int p) { trash.eb(p); }
il void clear_memPool() {
For(i, 1, cnt) T[i] = {};
trash.clear(), cnt = 0;
}
#define lc(p) (T[p].lc)
#define rc(p) (T[p].rc)
il void pushUp(int p) {
if (p)
T[p].sz = T[lc(p)].sz + T[rc(p)].sz + T[p].cnt;
}
il pii split(int p, int val) {
if (!p)
return {0, 0};
if (T[p].val <= val) {
pii q = split(rc(p), val);
T[p].rc = q.fi;
pushUp(p);
return {p, q.se};
} else {
pii q = split(lc(p), val);
T[p].lc = q.se;
pushUp(p);
return {q.fi, p};
}
}
il tuple<int, int, int> split_rk(int p, int rk) {
if (!p)
return {0, 0, 0};
if (T[lc(p)].sz >= rk) {
auto [l, mid, r] = split_rk(lc(p), rk);
lc(p) = r;
pushUp(p);
return {l, mid, p};
} else if (T[lc(p)].sz + T[p].cnt >= rk) {
int l = T[p].lc, r = T[p].rc;
T[p].lc = T[p].rc = 0;
pushUp(p);
return {l, p, r};
} else {
auto [l, mid, r] = split_rk(rc(p), rk - T[lc(p)].sz - T[p].cnt);
rc(p) = l;
pushUp(p);
return {p, mid, r};
}
}
il int merge(int p, int q) { // max p < min q
if (!p || !q)
return p | q;
if ((T[p].prio > T[q].prio) || (T[p].prio == T[q].prio && p > q))
return rc(p) = merge(rc(p), q), pushUp(p), p;
else
return lc(q) = merge(p, lc(q)), pushUp(q), q;
}
il void insert(int &p, int val) {
int x, y, z;
auto tmp = split(p, val);
z = tmp.se;
tmp = split(tmp.fi, val - 1);
x = tmp.fi, y = tmp.se;
if (y) {
assert(T[y].val == val);
T[y].cnt++;
} else {
y = newNode();
T[y].val = val, T[y].cnt = 1;
}
pushUp(y);
x = merge(x, y);
x = merge(x, z);
p = x;
}
il void erase(int &p, int val) {
auto tmp = split(p, val);
int x, y, z = tmp.se;
tmp = split(tmp.fi, val - 1);
x = tmp.fi, y = tmp.se;
if (y) {
assert(T[y].val == val);
T[y].cnt--, pushUp(y);
}
if (y && T[y].cnt)
x = merge(x, y);
x = merge(x, z);
p = x;
}
il int rank(int p, int x) {
auto tmp = split(p, x - 1);
int ans = T[tmp.fi].sz;
int p2 = merge(tmp.fi, tmp.se);
assert(p == p2);
return ans + 1;
}
il int kth(int p, int k) {
auto [l, mid, r] = split_rk(p, k);
int ans = T[mid].val;
int p2 = merge(l, merge(mid, r));
assert(p == p2);
return ans;
}
il int pre(int p, int x) {
auto tmp = split(p, x - 1);
auto [l, mid, r] = split_rk(tmp.fi, T[tmp.fi].sz);
int ans = T[mid].val;
int p2 = merge(merge(l, mid), tmp.se);
assert(p == p2);
assert(!r);
return ans;
}
il int nxt(int p, int x) {
auto tmp = split(p, x);
auto [l, mid, r] = split_rk(tmp.se, 1);
int ans = T[mid].val;
int p2 = merge(tmp.fi, merge(mid, r));
assert(p == p2);
assert(!l);
return ans;
}
}; // namespace FHQ
il void solver_main() {
// cerr << (ll(4e5 - 1) << 32) << ' ' << (ll(1) >> 32) << endl;
read(T);
while (T--) {
read(n, k);
For(i, 1, n) read(a[i]);
For(i, 1, k) read(b[i]);
ll ans = 0, b_inv = calc_B(), rt = 0;
FHQ::clear_memPool();
For(i, 1, n) {
(ans += b_inv) %= mod;
For(j, 0, 41) { // i 相比前面的数幂次高了 j
ll cur = ll(a[i]) << j;
ll val = i - FHQ::rank(rt, cur);
if (k - j > 0)
(ans += ll(k - j) * val % mod) %= mod;
}
For(j, 1, 41) { // i 相比前面的数幂次低了 j
ll cur = ll(a[i]) >> j;
ll val = i - FHQ::rank(rt, cur + 1);
if (k - j > 0)
(ans += ll(k - j) * val % mod) %= mod;
}
if (k > 41) { // // i 相比前面的数幂次低了 > 41
(ans += ll(k - 42 + 0) * (k - 41) % mod * (i - 1) % mod) %= mod;
}
FHQ::insert(rt, a[i]);
}
cout << ans << '\n';
}
}
} // namespace
signed main() { return solver_main(), 0; }