CF D 求调
  • 板块题目总版
  • 楼主Moeebius
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/12/25 00:40
  • 上次更新2023/12/25 00:53:57
查看原帖
CF D 求调
356003
Moeebius楼主2023/12/25 00:40

如题,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; }

2023/12/25 00:40
加载中...